给定一个有时间戳记录的SQL表。每隔一段时间,一个应用程序 App0
这样做 foreach record in since(certainTimestamp) do process(record); commitOffset(record.timestamp)
即周期性地消耗一批 "新鲜 "数据,按顺序处理并在每条记录后提交成功,然后在合理的时间内睡觉(以积累另一批数据)。这在单个实例中工作得很完美......但是如何平衡多个实例的负载呢?
在完全相同的环境下 App0
和 App1
同时 争夺新鲜数据。的想法是,随时查询执行的 App0
不得 叠加到由该函数执行的相同的读取查询中。App1
- 以至于它们永远不会尝试处理同一个项目。换句话说,我需要基于SQL的保证,保证并发读取查询返回不同的数据。这有可能吗?
P.S. Postgres是首选。
问题的描述相当模糊,什么是 "时间戳"?App1 该做 App0 正在处理之前选择的记录。在这个答案中,我做了以下假设。
certainTimestamp
是,而且它对所有 应用程序 每当他们开始一个DB查询时。 certainTimestamp
增长。 certainTimestamp
其他机构尚未处理的问题 应用程序. 这可以通过以下方式实现 锁定 许多SQL数据库中的记录。
一种方法是使用
SELECT ... FOR UPDATE SKIP LOCKED
这句话,结合范围选择的 since(certainTimestamp)
选择并锁定所有符合条件且当前未被锁定的记录。应用 实例运行这个查询时,它只得到 "剩下的 "要做的事情,并可以在这上面下功夫。
这就解决了 "覆盖" 或在同一数据上工作。
那么剩下的就是定义和更新了。certainTimestamp
.为了使这个答案简短,我在这里就不多说了,只是给上位者留下一个提示,那就是这个问题需要好好考虑一下,以避免出现这样的情况,比如说,一个单条记录因为某些原因无法处理,就会使 certainTimestamp
处于永久最低限度。