raft 节点如何了解对等节点?

问题描述

我刚刚完成了草稿纸,并开始着手实施。但是,我意识到我对一个关键细节有些困惑。 raft 节点如何“知道”它们的对等节点?我在论文中没有看到任何提及这一点,所以我认为它是特定于实现的,但在我看来,它会导致一些问题:

  • raft 集群的大小是静态的吗?由于每个节点都必须知道每个其他节点(为了发送 RPC),新节点将如何加入现有集群?现有节点将如何了解这个新节点?
  • 是否必须在初始化时将每个节点的网络位置硬编码到每个其他节点中?节点如何知道将其 RPC 发送到哪里?

非常感谢这方面的帮助。我真的很想完全理解 raft 并且很高兴能够实现它,但我对系统架构的这一部分有点迷茫。在我看来,应该使用硬编码的网络位置静态配置节点似乎是不对的,因为在现实世界中,我绝对可以想象需要将新节点添加到现有集群中。谢谢!

解决方法

成员变更是 Raft 协议的核心组成部分(在扩展论文的第 6 节中指定,并在 Diego 的论文中详细讨论)。但是你提出了一些很好的问题。在实践中,安全配置肯定有一些要求,并且在实际的 Raft 实现中也有一些常见的不同方法。

通常,有两种方法可以引导 Raft 集群:使用标识集群每个成员的配置初始化节点,或者使用单个节点启动集群并将节点添加到配置中(使用成员更改协议) 将集群扩展到其预期大小。两者都会给你相同的最终结果,这只是一个偏好问题。

集群配置的一个要求是每个成员都有一个固定的身份。如果追随者承认它在某个索引 i 之前保留了条目,并且领导者将该索引标记为已提交,则领导者应该能够假设条目 1-i 将存在于该追随者上永久,即使跟随者重新启动。因此,具有该标识的副本必须始终具有该日志。

但是这个要求给我们带来了另一个改变成员资格的用例:替换失败的成员。我希望跟随者的日志被破坏或主机崩溃并且永远不会返回,它应该只通过执行成员更改协议来替换:添加一个新副本并删除旧副本。同样,重要的是使用 Raft 文献中讨论的成员变更协议之一。

请记住,更改集群中的节点数量可能意味着仲裁大小也会发生变化,这就是成员身份更改难以处理的原因。更改仲裁大小时,协议需要确保提交仍存储在大多数节点上。为了安全地调整法定人数以避免中断,必须精确实施成员协议。