案例大师失败时的MongoDB一致性

时间:2018-01-11 00:30:05

标签: mongodb

假设我们有3节点副本集(1m,2s,3s)。 我们将在同一文档中应用几个连续更新:

  1. update1 {writeConcern:“most”} - >假设我们更新了1米和2秒 节点适当。
  2. update2 {writeConcern:“most”} - >假设我们更新了1米和3秒 节点
  3. 马上关机! (假设Oplog尚未完全同步)
  4. 问题:

    • 哪个节点将被选为主要节点?
    • 下次查找操作时将要阅读的文档状态是什么(readConcern =“most”/“local”)
    • 当主人回来时会发生什么?

1 个答案:

答案 0 :(得分:1)

步骤1和2是互斥的。其中一个将发生,但不是两个。这是因为MongoDB的oplog本质上是顺序的。

详细说明一下,我们假设步骤1和步骤2是及时的。

在第1步之后,oplog包含:Start -> update1

在第2步之后,oplog包含:Start -> update1 -> update2

在第3步之后,无论哪个节点包含最新数据(可能只有update1,或者update1update2,它都不会被选为主要数据。

下一次读入该集将返回在主要脱机之前设法复制的最新更新。当然,完全有可能两个更新都不会被复制,从而使下一个读取Start状态。关键是,该集合永远不会对更新顺序感到困惑。

如果新主节点仅包含update1(例如update2无法复制),那么当旧主节点重新联机时,它将进入ROLLBACK状态,它将删除update2的所有痕迹。因此,如果时机恰到好处,可能会失去update2

为避免在大多数情况下出现回滚,您需要使用写入关注majority执行写入操作,以便将update2复制到大多数投票节点,从而最大限度地减少它的可能性。回滚。

您描述的情景类似于"裂脑"在这种情况下,无法确定哪个更新是正确的。 MongoDB副本集协议专门用于避免这种情况。