Mongodb 客户机走进服务器并询问;什么';“什么是新的?”–;序列号问题

Mongodb 客户机走进服务器并询问;什么';“什么是新的?”–;序列号问题,mongodb,client-server,sync,Mongodb,Client Server,Sync,我正在寻找一种解决边缘情况的方案,在这种情况下,客户机不断地向服务器询问最新信息将失败 在本例中,由于另一个边缘情况问题,我没有使用时间戳。这是在这个问题中处理的: 假设我们使用的是序列号。有一个单一的序列号,每次表被更改时都会自动更新。更新任何行时,它都会记录当前序列。然后,这只是一个问题,客户要求什么是新的,因为它要求的最后一个序列。简单?是的,但是 故障场景: Sequence starts at 1 1) Client A starts update. Updates sequence

我正在寻找一种解决边缘情况的方案,在这种情况下,客户机不断地向服务器询问最新信息将失败

在本例中,由于另一个边缘情况问题,我没有使用时间戳。这是在这个问题中处理的:

假设我们使用的是序列号。有一个单一的序列号,每次表被更改时都会自动更新。更新任何行时,它都会记录当前序列。然后,这只是一个问题,客户要求什么是新的,因为它要求的最后一个序列。简单?是的,但是

故障场景:

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,所以我不相信我们可以在更新过程中轻松锁定序列。如果可以的话,我担心性能

让客户反复询问“新内容”似乎是一个常见的用例,我发现在这方面没有找到更多的最佳实践是令人惊讶的


关于解决此方案或推荐更好的、最好是平台无关的、用于请求更改的解决方案,您有什么想法吗?

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

  • 当你抓取一个序列号时,把它放在一张“正在使用”的地图上
  • 对该序列号进行更改后,请将其从“正在使用”std::集合中删除
  • 跟踪集合中的最小值。当最小值从“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数据的可裁剪游标。

这澄清并提供了Zardosht Kasheff的correc的一些示例我不能回答上面的问题

  • 在更新开始时,我们将序列号添加到正在使用的列表中
  • 任何请求“最新信息”的客户端都不能请求任何>=列表中最低数字的内容
  • 因此,如果一对客户机使用序列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.
序列从1开始
客户端A启动更新。使用序列2。正在使用的表现在有“2”
客户端B开始更新。使用序列3。正在使用的表现在有“2,3”
客户端B使用序列3更新行。正在使用的表现在有“2”
客户端C希望请求>1。然而,最小使用表是2。所以它请求>1和1。获取A和B。
还有扎尔多什特的例子

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.
客户端以序列11、12、13、14、15和16启动更新。正在使用的表是“11、12、13、14、15和16”
更新12、13、11完成。正在使用的表为“14、15、16”
客户端C希望请求>1。允许>1和13。得到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
客户端以序列11、12、13、14、15和16启动更新。正在使用的表是“11、12、13、14、15和16”
更新12,16,11完成。正在使用的表是“13,14,15”
客户端C希望请求>1。允许>1和12。获取13、14、15和16

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

客户端a的更改和客户端C的更改之间有什么区别?您等待的时间有多长?如果客户端C询问“有什么新内容?”?"同样,他是否得到客户A的更改?在本例中,客户C不提交更改。客户C不会在上面得到客户A的更改,因为他不会要求足够低的序列号。我唯一的想法是,最小值应该是客户收到的最后一个序列,而不是在用表中定义的最小值。例如,在y中我们更复杂的情况下,客户端C进入更新可能会读到1,我可能误解了一些东西,但是在更新过程中,11是使用表中最低的,不是14。这个想法是,即使12和13已经完成,因为11没有,12和13还没有被客户端C读取。完成11后,还有另一个隐式细节,即当在用表为空时,客户端C可以读取所有存在的内容。按照以下顺序完成:12、13,-客户端读取-、11、15、14、16,您是正确的。11是在用表中的最低值。但是,您的原始示例的客户端读取顺序如下所示r:12,13,11,-客户端读取-,15,14,16,您是正确的。在本例中,14是最低的。我刚刚澄清,客户端应该要求sequence>clientLastSequenceReceived和sequence