我有一个难题,也许你可以帮助我。
我有一个用作工作队列的表。记录已插入并需要处理。处理完一条记录后,将其从队列中删除。有一些限制:
- 在任何给定时间只有一个实体可以处理记录(“实体”是指:一个线程或连接到同一数据库的单独计算机)
- 实体有些动态。它们可能会改变(实体的数量或特征)
- 实体在 1 笔交易中处理记录
- 处理必须并行进行(如果实体 1 选择批次 1,实体 2 必须能够并行处理批次 2,无需等待实体 1 完成处理)
- 一旦实体选择了要处理的记录,则该记录所属的整个“批次”记录不得被其他实体选择。当我说“批处理”时,我的意思是该表(逻辑上)组织如下:
- 第 1 行(批次 1)
- 第 2 行(第 1 批)
- 第 3 行(第 2 批)
- 第 4 行(第 2 批)
- 第 5 行(第 2 批)
- .... 等等。
因此,假设 entity1 和 entity2 都想从表中选择一个处理切片。如果 entity1 选择 row1,则 entity2 可以选择除 batch1 之外的任何其他内容(除 row1 和 row2 之外的任何其他内容)。
让我们抽象出处理部分,因为实际处理是什么并不重要。我很想知道如何阻止实体相互冲突,只使用 mysql 数据库,同时保持处理的并行性。
从我的角度来看,我看到了两个非常普遍的方向:
- 使用某种状态字段,这表明特定实体已经选择了一批,并且必须将这个从未来的选择中排除。这个想法的缺点是如果选择批次的实体崩溃了,那么恢复其他实体的处理有点困难。
- 使用mysql的锁,缺点是难以保证并行处理,而且不是顺序的。例如,我可以为实体 1 选择...进行更新。但是 entity2 不能执行相同的 select... for update,因为这将等待第一个实体完成处理,然后再获取它需要的批次。
我有兴趣知道:
- 哪个方向将导致最小的编码工作
- 我在这里还缺少其他方向吗(请记住,除了通过数据库之外,实体无法相互通信)
- 如果有这类问题的标准模式
- 如果你能指出一篇讨论这类问题的文章。
- 解决这个问题的最有效方法是什么。
所以我在这里是数据库必须在不同实体之间拆分一个表,以便处理,并且想知道最好的方法。我几乎不认为我是第一个处理这个问题的人,我想知道你的想法。另外,请注意,可以通过相当简单的标准(例如,batchId)分批拆分记录
亲切的问候,
安德烈。