是在分布式存储中实现线性化所必需的复制日志



etcd使用的Raft算法和Zookeeper使用的ZAB算法都在使用复制日志来更新状态机。

我想知道是否可以通过简单地使用领导人选举和版本化的价值观来设计一个类似的系统。以及为什么这些系统决定使用复制日志。

我的例子是,如果我们有以下设置

  • 机器A(Leader),包含版本1
  • 机器B(追随者),包含版本1
  • 机器C(Follower),包含版本1

写的是这样的:

  1. 机器A接收写入请求并存储挂起的写入V2
  2. 机器A向机器B和机器C发送准备请求
  3. 跟随者(机器B和机器C)向引导者(机器A)发送确认
  4. Leader(机器A)从机器的quorum收到确认后,它知道V2现在已提交并向客户端发送成功响应
  5. Leader(机器a)向Follower(机器a和机器B)发送完成请求,通知他们V2已提交,V1可以丢弃

为了使该系统工作,在获得leader Lease后进行leader更改时,leader机器必须在接受请求之前通过读取节点的法定数量来获得最新的数据版本。

ETCD中的raft算法和Zookeeper中的ZAB算法都使用复制日志来更新状态机。我想知道是否可以通过简单地使用领导人选举和版本化的价值观来设计一个类似的系统。

是的,可以在没有日志复制的情况下实现一致性/线性化。最初,共识问题在Leslie Lamport(1998)的Paxos Made Simple论文中得到了解决。他描述了两种算法:单命令Paxos用于构建分布式线性化一次写入寄存器,多命令Paxo用于在仅附加日志(一次写入的有序寄存器阵列)上创建分布式状态机。

只附加日志是比一次写入寄存器更强大的抽象,因此人们选择日志而不是寄存器并不奇怪。此外,在Vertical Paxos(2009)发表之前,日志复制是唯一能够更改集群成员身份的共识协议;对于多个任务来说至关重要的是:如果不能替换出现故障的节点,那么集群最终将变得不可用。

然而,垂直帕克索斯是一篇很好的论文,通过联合共识,我更容易理解拉夫特关于集群成员的想法,所以我写了一篇关于如何将拉夫特的方式适应单一法令帕克索斯的帖子。

随着时间的推移,单一法令Paxos的"一次写入"性质也得到了解决,将一次写入寄存器转变为分布式线性化变量,这是一个非常强大的抽象,适用于许多用例。在野外,我在树型数据库中看到了这种方法。如果你感兴趣的话,我在博客上写了关于这个改进的SDP的文章。

因此,现在当我们有了日志的替代方案时,考虑它是有意义的,因为基于日志的复制很复杂,并且有内在的局限性:

  • 对于日志,您需要关心日志压缩和垃圾收集
  • 日志的大小受一个节点的大小限制
  • 用于拆分日志和迁移到新集群的协议并不为人所知

以及为什么这些系统决定使用复制日志。

基于日志的方法比其他方法更古老,因此它有更多的时间来获得流行。

关于您的示例

很难对其进行评估,因为你没有描述领导人选举是如何进行的,领导人之间的冲突是如何解决的,处理失败的策略是什么,以及如何改变集群的成员资格。

我相信,如果你仔细描述它们,你会得到帕克索斯的变体。

您的示例是有意义的。然而,您是否考虑过每一种可能的失败情况?在步骤2中,由于网络分区或路由器故障,机器B可能在机器C之前或之后几分钟接收到消息(反之亦然)。在步骤3中,确认可能会丢失、延迟或多次重新发送。领导人也可能失败,并在同一轮共识中复出一次、两次或可能几次。在步骤5中,消息可能丢失、重复或机器A&C可以收到通知,而B没有收到…

概念的简单性,也称为"减少潜在的故障点",是分布式系统的关键。任何事情都有可能发生,发生在现实环境中。原语,例如基于共识协议的复制日志,在任何环境中都被证明是正确的,是构建更高抽象级别的坚实基础。的确,通过定制的算法可以实现更好的性能或延迟或"感兴趣的指标",但确保这种算法的正确性是一项重要的时间投资。

复制日志简单、易于理解、可预测,并且完全属于已建立的共识协议(paxos、paxos变体和raft)的领域。这就是它们受欢迎的原因。这并不是因为它们最适合任何特定的应用程序,而是因为它们被理解和可靠。

有关相关参考资料,您可能有兴趣了解Paxos和云中的共识:Paxos Systems解密

最新更新