RAFT共识协议 - 在提交之前条目应该是持久的

时间:2014-04-29 07:31:15

标签: consensus raft

我有关于实现RAFT的以下查询:

考虑以下场景\实现:

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

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

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

3 个答案:

答案 0 :(得分:3)

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

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

引用迭戈的回答:

  

为了安全,即使面对相关的停电,大部分也是如此   服务器需要在其效果之前保留日志条目   外部化。任何少于多数的人和那些服务器都可以   永久失败,导致数据丢失/损坏

Ben Johnson's引用我的电子邮件中引用相同的内容:

  

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

     

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

     
      
  1. 节点A复制节点B的条目。

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

  4.   
  5. 节点A现在有一个法定人数并提交该条目。

  6.   
  7. 然后节点A被分区远离节点B&下进行。

  8.   
  9. 节点B随后死亡并丢失该条目的内存副本。

  10.   
  11. 节点B重新启动。

  12.   
  13. Node B& C然后选择一个领导者,“已提交”的条目将不在他们的日志中。

  14.   
  15. 当节点A重新加入群集时,它将具有不一致的日志。该条目将被提交并应用于状态机   它无法回滚。

  16.         

答案 1 :(得分:0)

我不同意接受的答案。

  1. 磁盘并不持久。假设磁盘在服务器本地,则它可能会永久失败。因此,很显然,写入磁盘并不能使您免于遭受损失。复制持久性,前提是副本位于不同的故障域中,如果您认真考虑持久性,它们将是持久性的。当然,磁盘不受此过程的危害有很多(Linux oom被杀死,一般的oom,电源等),但是专用计算机上的专用进程可以很好地完成任务。尤其是如果日志存储为ramfs,则进程重启不是问题。

  2. 如果日志存储丢失,则主机标识也应丢失。 A,B,C标识日志。新日志,新ID。 B(潜在的)存储丢失后“重新加入”只是一个错误的实现。新流程无法声明B的身份,因为它无法确定它具有B拥有的所有信息。就像在总是刷新到磁盘的情况下(如果我们更换了承载B的计算机的磁盘)一样,我们不能只是将其配置为具有B的身份来重新启动该过程。那是胡说八道。在两种情况下,它都应以D重启,然后要求加入集群。在这一点上,丢失已写入内容的问题在烟熏中消失了。

答案 2 :(得分:0)

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

让我们以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丢失。因此,我认为未提交的条目也应该是持久的。