【问题标题】:MongoDB consistency in case master goes down万一 master 宕机时的 MongoDB 一致性
【发布时间】:2018-01-11 12:00:37
【问题描述】:

假设我们有 3 节点副本集 (1m,2s,3s)。 我们将在同一个文档上应用一些顺序更新:

  1. update1 {writeConcern: "majority"} -> 假设我们更新了 1m 和 2s 适当的节点。
  2. update2 {writeConcern: "majority"} -> 假设我们更新了 1m 和 3s 节点
  3. 立即关闭master! (假设 Oplog 尚未完全同步)

问题:

  • 哪个节点将被选为主节点?
  • 在下一次查找操作中读取文档的状态是什么(readConcern = "majority" / "local")
  • 在这种情况下,当主人回来时会发生什么?

【问题讨论】:

    标签: mongodb


    【解决方案1】:

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

    为了详细说明,我们假设步骤 1 和步骤 2 在时间上是连续的。

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

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

    在第3步之后,无论哪个节点包含最新数据(可以是update1,也可以是update1和update2,都没有关系)将被选为主。

    对集合的下一次读取将返回在主节点离线之前成功复制的最新更新。当然,完全有可能不会复制任何更新,从而使下一次读取处于Start 状态。关键是,集合永远不会对更新顺序感到困惑。

    如果新的主节点只包含update1(例如,update2 没有成功复制),那么当旧的主节点重新上线时,它将进入ROLLBACK 状态,在那里它将删除所有跟踪的update2。因此,如果时机恰到好处,可能会失去update2。

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

    您描述的场景类似于“脑裂”场景,无法判断哪个更新是正确的。 MongoDB 副本集协议就是专门为避免这种情况而设计的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-08
      • 1970-01-01
      • 1970-01-01
      • 2016-06-15
      • 2012-08-11
      • 2016-04-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多