客户端进入服务器并询问“什么是新的?” - 序列号问题

时间:2014-02-05 19:34:16

标签: mongodb client-server sync

我正在寻找边缘案例场景的解决方案,其中客户端不断向服务器询问新内容将会失败。

在这个例子中,由于另一个边缘情况问题,我没有使用时间戳。这是在这个问题中处理的:A Client Walks Into a Server And Asks "What's New?" – Problems With Timestamps

假设我们正在使用序列号。每次更改表时,都会有一个序列号以原子方式更新。更新任何行时,它会记录当前序列。然后,这只是客户询问自其要求的最后一个序列以来的新内容。简单?是的,但是......

失败情景:

Sequence starts at 1
1) Client A starts update. Updates sequence to 2
2) Client B starts update. Updates sequence to 3
3) Client B updates rows with sequence 3
4) Client C requests changes >1.  Gets B's changes. Good.
5) Client A updates rows with sequence 2. 
6) Client C requests changes >3.  Gets nothing. Doesn’t get Client A’s changes.

因为我们使用的是MongoDB,所以我不相信我们可以在更新过程中轻松锁定序列。而且,如果可以,我担心性能。

让客户反复询问“什么是新的”似乎是一个常见的用例,我发现在这方面找不到更好的最佳实践,我感到很惊讶。

有关解决此方案或建议更好的,最好是平台无关的解决方案以寻求更改的任何想法吗?

2 个答案:

答案 0 :(得分:1)

您可以做的一件事是维护一堆正在使用的序列号以及“要分配的下一个序列号”。请尝试以下方法:

  • 当您获取序列号时,请将其置于“使用中”地图中。
  • 完成对序列号的更改后,将其从“使用中”std :: set
  • 中删除
  • 跟踪集合中的最小值。每当最小值从“x”变为“y”时,客户端C请求值从x到y,但不大于y。

因此,在您的示例中,当您将序列更新为2时,1将被放入正在使用的集合中。然后,当你更新到3时,2放在那里,并且集合包含1和2.当完成2的工作时,2从集合中删除,但是客户端C没有接受任何更改,因为最小值, 1,没有变化。当客户端A使用1时,最小值从1变为3,客户端C可以从1到3读取更改。

对于更复杂的示例,假设您有6个客户端使用序列号11,12,13,14,15和16,但按以下顺序完成:12,13,11,15,14,16(其中它是从“使用中”集合中删除的顺序。在这个例子中,在11消失之后,客户端C可以读取11到13,因为最小值从11变为14.然后,在14消失之后,客户端C可能会读取14和15,因为最小值从14变为16.然后,当16消失时,客户端C可以读取16。

这基本上是我们在TokuMX复制中使用的算法,它决定哪些oplog条目可以复制到辅助节点。客户端A和B将是执行写入oplog的线程,而客户端C将是来自辅助提取oplog数据的可用游标。

答案 1 :(得分:0)

这是澄清并提供Zardosht Kasheff上面正确答案的一些例子。

  • 在更新开始时,我们将序列号添加到正在使用的列表中
  • 任何请求“新内容”的客户都无法提出任何要求> =列表中的最低号码。
  • 因此,如果一对客户正在使用序列10,11,12进行更新,则客户端会要求提供来自>的所有内容。 sequenceOfLastItemReceivedByClient和< 10(使用清单中的最低编号。)

这是我原来的例子解决了:

Sequence starts at 1
Client A starts update. Uses sequence 2.  In use table now has “2"
Client B starts update. Uses sequence 3. In use table now has “2,3"
Client B updates rows with sequence 3. In use table now has “2"
Client C wants to request >1 .  However, min in-use table is 2.  So it requests >1 and <2 which is none.
Client A updates rows with sequence 2. In use table now empty.
Client C wants to request changes >1. Gets A and B.

和Zardosht的例子

Clients start updates with sequences 11, 12, 13, 14, 15, and 16. In use table is "11, 12, 13, 14, 15, 16”
Updates 12, 13, 11 finish.  In use table is “14, 15, 16”
Client C wants to request >1.  Is allowed >1 and <14.  Gets sequences 11, 12, 13
Updates 15, 14, 16 finish.  In use table is empty.
Client C requests >13. Gets 15, 14, 16.

最后一个例子:

Clients start updates with sequences 11, 12, 13, 14, 15, and 16. In use table is "11, 12, 13, 14, 15, 16”
Updates 12, 16, 11 finish.  In use table is “13, 14, 15”
Client C wants to request >1.  Is allowed >1 and <13.  Gets sequences 11, 12
Updates 13, 14, 15 finish.  In use table is empty.
Client C requests >12. Gets 13, 14, 15, 16

以上所有例子都通过了。这似乎是一个可行的解决方案。