【问题标题】:RAFT consensus protocol - Should entries be durable before commitingRAFT 共识协议 - 在提交之前条目是否应该是持久的
【发布时间】:2014-04-29 07:31:15
【问题描述】:

我对实现 RAFT 有以下疑问:

考虑以下场景\实现:

  1. RAFT 领导者收到一个命令条目,它将条目附加到一个 内存数组然后将条目发送给追随者(使用 心跳)
  2. 追随者收到条目并将其附加到他们的 内存中的数组,然后发送它已收到的响应 进入
  3. 然后领导者通过将条目写入持久性来提交条目 store (file) 领导者发送最新的提交索引在 心跳
  4. 跟随者然后根据领导者提交条目 通过将条目存储到其持久存储(文件)来提交索引

RAFT 的一个实现(链接:https://github.com/peterbourgon/raft/)似乎以这种方式实现它。我想确认一下是否可以。

如果条目由领导者和追随者“在内存中”维护直到它被提交,是否可以?这种情况在什么情况下会失败?

【问题讨论】:

    标签: consensus raft


    【解决方案1】:

    我不同意接受的答案。

    1. 磁盘并不是很耐用。假设磁盘是服务器本地的,它可能会永久失败。所以很明显,写入磁盘并不能让你摆脱这种情况。复制持久性,前提是副本存在于不同的故障域中,如果您认真对待持久性,它们将会是。当然,磁盘不会遭受的进程有很多危害(linux oom 被杀死,一般的 oom,电源等),但是专用机器上的专用进程可以做得很好。特别是如果日志存储是 ramfs,那么进程重启不是问题。

    2. 如果日志存储丢失,那么主机身份也应该丢失。 A、B、C 识别日志。新日志,新标识。 B 在(潜在的)存储丢失后“重新加入”只是一个错误的实现。新进程不能声称 B 的身份,因为它不能确定它拥有 B 拥有的所有信息。就像总是刷新到磁盘的情况一样,如果我们更换托管 B 的机器的磁盘,我们不能只是重新启动进程并将其配置为具有 B 的身份。那将是无稽之谈。在这两种情况下,它都应该以 D 的身份重新启动,然后要求加入集群。到那时,丢失已提交写入的问题就烟消云散了。

    【讨论】:

      【解决方案2】:

      我通过发布到 raft-dev 谷歌组找到了问题的答案。我已经添加了答案以供参考。

      请参考:https://groups.google.com/forum/#!msg/raft-dev/_lav2NeiypQ/1QbUB52fkggJ

      引用迭戈的回答:

      为了安全,即使面对相关的停电,大多数 服务器需要在其效果生效之前持久化日志条目 外化。任何少于多数,这些服务器可以 永久失败,导致数据丢失/损坏

      引用Ben Johnson's 回复我的电子邮件:

      不,服务器必须先将条目刷新到磁盘才能被视为一部分 法定人数。

      例如,假设您有一个名为 A、B 和 C 的节点集群 其中 A 是领导者。

      1. 节点 A 将条目复制到节点 B。

      2. 节点 B 在内存中存储条目并响应节点 A。

      3. 节点 A 现在具有仲裁并提交条目。

      4. 然后节点 A 与节点 B 和 C 分开。

      5. 然后节点 B 死亡并丢失该条目的内存副本。

      6. 节点 B 重新启动。

      7. 当节点 B 和 C 去选举领导者时,“已提交”条目将不会出现在他们的日志中。

      8. 当节点 A 重新加入集群时,会出现不一致的日志。该条目将已提交并应用于状态机,因此 无法回滚。

      【讨论】:

      • 我相信在第 6 步节点 B 需要在加入之前读取机器的法定人数以获取最新提交的索引。但这是不可能的,因为节点 A 仍然是分区的。所以应该发生的是节点 B 应该保持待机模式直到节点 A 加入,然后节点 B 将从节点 A 读取最新提交的索引。另一个选项是如果在第 4 步中 B 或 C 成为领导者,它将需要 2投票,因此最新提交的条目将存储在两个节点(B&C)上
      【解决方案3】:

      我认为条目在提交之前应该是持久的。

      我们以 Raft 扩展论文的图 8(e) 为例。如果提交时条目是持久的,则:

      1. S1 将 4 复制到 S2 和 S3,然后提交 2 和 4。
      2. 所有服务器崩溃。因为 S2 和 S3 不知道 S1 已提交 2 和 4,所以他们不会提交 2 和 4。因此 S1 已提交 1、2、4,S2、S3、S4、S5 已提交 1。
      3. 除 S1 之外的所有服务器都重新启动。
      4. 因为只有提交的条目是持久的,所以 S2、S3、S4、S5 具有相同的单个条目:1。
      5. S2 被选为领导者。
      6. S2 将新条目复制到除崩溃的 S1 之外的所有其他服务器。
      7. S1 重新启动。因为 S2 的条目比 S1 新,所以 S1 的 2 和 4 被之前的新条目替换。

      因此,已提交的条目 2 和 4 丢失。所以我认为未提交的条目也应该是持久的。

      【讨论】:

      • 并非如此。在仅内存的情况下,实现进程崩溃是需要新身份加入集群的永久故障。如果您同时杀死每台服务器,那么您已经违反了 N = 2f - 1 条件,并且您的集群是 toast。维护其身份但不维护其日志的进程有问题无论是单个本地磁盘、raid 阵列、进程内存、tmpfs、SAN 阵列还是其他任何东西。
      猜你喜欢
      • 2016-03-29
      • 2011-02-06
      • 2019-02-07
      • 2019-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-09
      • 2014-11-08
      相关资源
      最近更新 更多