分布式一致性算法

概述

分布式一致性算法是一组用于确保分布式系统中数据一致性的算法。这些算法旨在解决多个节点之间的数据同步和一致性问题,以确保在分布式环境中的各个节点上的数据副本保持一致。

一些常见的分布式一致性算法包括:

  1. Paxos算法:Paxos算法是一种经典的分布式一致性算法,用于确保在网络中多个节点之间达成一致性协议。
  2. Raft算法:Raft算法是另一种用于分布式一致性的算法,它的设计更加容易理解和实现,适用于构建可靠的分布式系统。
  3. ZAB 算法:ZAB(ZooKeeper Atomic Broadcast)选举算法是为 ZooKeeper 实现分布式协调功能而设计的。
  4. Gossip算法:Gossip算法,是一种分布式计算中常用的算法,它用于在一个分布式系统中传播信息或数据,以实现数据的一致性和同步。

算法简单介绍

Paxos算法

Paxos算法是一种分布式一致性算法,用于在分布式系统中达成一致的共识。它是由Leslie Lamport于1990年提出的,被认为是分布式系统领域的经典算法之一。Paxos算法的主要目标是允许多个节点在面对故障和网络延迟的情况下,达成共识,确保数据的一致性;Paxos算法的核心思想是通过多轮的消息传递和投票来达成共识

关键概念:

  1. 提议者(Proposers):提议者是试图向系统提交一个值的节点。每个提议者会生成一个提案(Proposal),其中包含一个提案号(Proposal Number)和一个值。提案号是唯一 标识提案的,通常包括一个提议者的标识符和一个递增的序号。
  2. 学习者(Learners):学习者是节点,它们等待系统中的大多数节点接受相同的提案,以达成共识。一旦学习者确定了共识值,它们就会学到这个值,即状态转移过程
  3. 接受者(Acceptors):接受者是节点,它们用来接受提议并投票是否接受提案。每个接受者可以接受一个提案,并在接受提案后通知其他节点。接受者可以有不同的投票策略,但通常选择接受具有最高提案号的提案。

基本流程:

  • 准备阶段:
    1. 提议者选择一个唯一的提案号,并向接受者发送一个准备请求(Prepare Request)包含该提案号。
    2. 每个接受者比较提案号,如果接受者之前已经回应过更高提案号的准备请求,则拒绝请求。否则,接受者返回一个承诺不再接受低于该提案号的提案,并返回之前已经接受的提案(如果有的话)。
    3. 提议者收到多数接受者的承诺后,进入下一阶段。
  • 提议阶段:
    1. 提议者向多数接受者发送一个提案请求(Accept Request),包含提案号和值。
    2. 每个接受者检查提案号是否是它之前承诺的最高提案号,如果是,则接受提案,并将提案号和值广播给其他节点。
    3. 学习者在收到多数节点(一半以上)的接受消息后,确定了共识值。

优点:

  1. 一致性保证:Paxos算法能够确保在分布式系统中的所有节点之间达成一致性,即使在面临网络故障和节点故障的情况下也能够保持一致。
  2. 容错性:Paxos是一种具有强容错性的算法,可以处理节点故障、消息丢失等异常情况,保证系统的可用性和一致性。

缺点:

  1. 复杂性:Paxos算法的实现和理解相对复杂,它包括多个阶段和消息交互,需要谨慎设计和调试,容易出现错误。
  2. 性能开销:Paxos算法在某些情况下(因为消息交互次数多)可能会引入较大的性能开销,特别是在网络通信和消息传递方面,可能导致延迟增加。

Raft算法

Raft算法是一种用于分布式一致性的算法,类似于Paxos,但它旨在更易于理解和实现。Raft算法由Diego Ongaro和John Ousterhout于2013年提出,并已成为分布式系统中常用的共识算法之一,尤其在分布式数据库和分布式存储系统中得到广泛应用。

Raft算法的设计目标是提供更直观的分布式一致性解决方案,通过将问题分解为可管理的部分,使得算法更容易理解和实现。

关键概念:

  1. 领导者(Leader):领导者是Raft算法中的核心节点,主要负责日志复制、心跳检测等工作。
  2. 跟随者(Follower):跟随者是Raft算法中的被动节点,只响应来自领导者和候选者的消息。
  3. 候选者(Candidate):候选者是Raft算法中的中间状态,用于领导者选举过程。

步骤:

  1. 领导者选举

    • 在一个Raft集群中,只有领导者可以接受客户端的请求并将其复制到日志中。
    • 领导者选举使用随机化的定时器心跳机制来实现。候选者节点发起选举,并需要获得多数节点的支持才能成为领导者。

    超时机制(随机):因为随机可以规避多领导者竞选

    • Follower等待心跳超时
    • 等待选举投票超时

    投票规则:

    • term大的成员拒绝投票给term小的RequestVote消息。
    • 最后一条日志项编号大的拒绝投票给最后一条日志项编号小的成员。
    • 每个成员,一届term任期内只投出一张选票,先来先获得投票。
  2. 日志复制:日志项是连续的

    • 领导者负责将客户端的操作添加到日志中,并将日志复制到其他节点。这确保了所有节点都具有相同的操作序列。
    • 跟随者节点在接收到领导者的日志条目后,将其附加到本地日志。
  3. 安全性

    • Raft算法使用严格的一致性模型,确保只有领导者可以接受客户端的请求,这样避免了分布式系统中的多个领导者问题。
    • 安全性还包括数据持久性,即数据在节点故障时不会丢失。Raft要求领导者在接收请求后必须等待大多数节点的确认后才能提交日志条目。

优点:

  1. 简单性:Raft的设计目标之一是提供更容易理解和实现的共识算法。相对于Paxos等复杂的算法,Raft的概念更直观,因此更容易实现和维护。
  2. 安全性:Raft算法在保证分布式系统的安全性方面表现出色。它确保当大多数节点正常运行时,系统能够达成共识,从而防止数据丢失或损坏。
  3. 选举机制:Raft使用选举机制来选举领导者,确保系统中的节点能够动态适应节点故障和网络分区等情况。这有助于系统的可用性和容错性。
  4. 日志复制:Raft通过日志复制来确保系统的一致性。这种方式更直观,易于理解,并且能够有效地处理数据复制和恢复。

缺点:

  1. 性能开销:Raft算法的性能开销相对较高,尤其是在大规模分布式系统中。这主要是因为它需要维护额外的状态和进行领导者选举。
  2. 限制:Raft算法对网络分区(节点之间的通信中断)的处理方式相对保守。虽然这有助于确保一致性,但在某些情况下可能导致系统不可用。

相对于Paxos,Raft更易于理解和实现,因此在实际应用中更受欢迎。它提供了一种直观的方式来处理分布式一致性问题,有助于开发人员更容易地构建可靠的分布式系统。

ZAB 算法

ZAB(ZooKeeper Atomic Broadcast)选举算法是为 ZooKeeper 实现分布式协调功能而设计的。相较于 Raft 算法的投票机制,ZAB 算法增加了通过节点 ID 和数据 ID 作为参考进行选主,节点 ID 和数据 ID 越大,表示数据越新,优先成为主。

关键概念:

  1. 领导者(Leader):Zookeeper集群的核心角色,在集群启动或崩溃恢复中通过Follower参与选举产生,为客户端提供读写服务,并对事务请求进行处理
  2. 跟随者(Follower):Zookeeper集群的核心角色,在集群启动或崩溃恢复中参加选举,没有被选上就是这个角色,为客户端提供读取服务,也就是处理非事务请求,Follower不能处理事务请求,对于收到的事务请求会转发给Leader。
  3. 观察者(Observer):观察者角色,不参加选举,为客户端提供读取服务,处理非事务请求,对于收到的事务请求会转发给Leader。使用Observer的目的是为了扩展系统,提高读取性能。
  4. 成员状态:
    • LOOKING: 竞选状态,没有Leader。
    • FOLLOWING: 随从状态,同步Leader 状态,参与Leader选举的投票过程。
    • OBSERVING: 观察状态,同步Leader 状态,不参与Leader选举的投票过程。
    • LEADING: 领导者状态,存在Leader。

步骤:

  • 选举阶段: 在选举阶段,ZAB算法用于选举一个领导者节点,这个领导者节点将负责处理所有写操作和数据复制。在分布式系统中,只有一个领导者能够进行写操作,以确保一致性。选举过程包括节点的争夺和选举出领导者,通常采用基于投票的机制,其中大多数节点投票给同一个节点成为领导者。
  • 成员发现: 成员发现阶段是指ZAB算法用于检测集群中的新节点或失效节点,并确保所有节点都知道当前的集群成员。这一阶段确保节点的动态加入和离开不会破坏共识算法的正常运行
  • 数据同步: 一旦选出领导者,领导者负责接受客户端的写请求,并将这些写请求转化为一个序列的提案(proposal)。然后,领导者将这些提案发送给集群中的其他节点以进行复制。数据同步阶段确保集群中的所有节点都有相同的数据状态,以维护一致性。
  • 数据广播: 在数据广播阶段,领导者将接受到的提案广播给集群中的其他节点,这些节点将按照相同的顺序应用这些提案,从而确保各节点的数据状态保持一致。一旦多数节点成功应用了提案,数据就被视为已经提交,并且可以告知客户端,从而完成一次写操作

优点:ZAB协议优点是在保证数据一致性的同时,具有高可用性和可扩展性。

缺点:

  1. 内存占用多:ZAB协议缺点是需要占用大量的内存和存储空间来记录节点状态。
  2. 选主开销:在选主过程中,需要进行领导者选举,这会引入额外的开销和延迟。
  3. 单一领导者:ZAB算法采用了单一领导者模式,这意味着所有的写操作都必须经过领导者,可能会成为性能瓶颈。

Gossip算法(复制算法)

Gossip算法,又称八卦算法,是一种用于分布式系统中的信息传播和数据同步的算法。它的工作方式类似于人们之间传播八卦或谣言的方式,通过节点之间相互交流信息来实现分布式系统的协调和数据一致性。

节点状态:

  • Susceptible (S): “Susceptible” 节点是指在 Gossip 协议中可能会传播消息即未传播的节点。这些节点处于接收消息的状态,它们会接受来自其他节点的信息并可能将其传播给其他节点。当一个节点接收到消息时,它可以变为 “Infective” 状态。
  • Infective (I): “Infective” 节点是已经接收了消息并可以传播消息的节点。这些节点会将他们接收到的消息传播给其他节点,以便在系统中传播信息和状态。当一个节点变为 “Infective” 状态后,它可以传播消息给其他节点,并继续保持 “Infective” 状态,以确保消息能够传播到系统中的其他节点。
  • Recovered (R): “Recovered” 节点是指已经接收并传播了消息的节点,但它们不再继续传播相同的消息。这些节点可以被认为是已经处理了消息并不再活跃地传播它们。在某些 Gossip 协议中,节点可能会从 “Infective” 状态转变为 “Recovered” 状态,以限制消息的传播范围。

复制方式:

  • 直接邮寄:就是指你的节点收到更新数据的时侯直接把这个数据发送给其它的节点。

  • 反熵:每个节点周期性地随机选择其他节点(一般是采用闭环结构),然后通过互相交换自己的所有数据来消除两者之间的差异,直到整个网络中节点数据一致。

  • 谣言传播:

    各节点周期性的,向随机的一组节点广播更新数据。

    其他节点收到更新的数据后,继卖周期性的,向随机的一组节点广播更新数据,直到所有节点都处理了新数据。

    为了使谣言传播能够停止(避免广播风暴) ,gossip增加removed状态,当节点收到的谣言并且该谣言处于removed (之前已经处理过的谣言)时,该节点将不继续传播该谣言。

特点:

  1. 去中心化,集群中各个节点都是对等的。
  2. 无法保证在某个时刻所有节点状态一致。
  3. 比较适合小数据量的同步。失败检测、路由同步、Pub/Sub、动态负载均衡。

Distro协议

Distro算法是集Gossip以及 Eureka协议的优点并加以优化而出来的,对于原生的Gossip,由于随机选取发送消息的节点,也就不可避免的存在消息重复发送给同一节点的情况,增加了网络的传输的压力,也给消息节点带来额外的处理负载,而Distro算法引入了权威Server的概念,每个节点负责一部分数据以及将自己的数据同步给其他节点,有效的降低了消息冗余的问题。

步骤:

  • Nacos 启动时首先从其他远程节点同步全部数据。
  • Nacos 每个节点是平等的都可以处理写入请求,同时把新数据同步到其他节点。
  • 每个节点只负责部分数据,定时发送自己负责数据的校验值到其他节点来保持数据一致性。
  • 当该节点接收到属于该节点负责的服务时,直接写入。
  • 当该节点接收到不属于该节点负责的服务时,将在集群内部路由,转发给对应的节点,从而完成写入。
  • 读取操作则不需要路由,因为集群中的各个节点会同步服务状态,每个节点都会有一份最新的服务数据。
  • 而当节点发生宕机后,原本该节点负责的一部分服务的写入任务会转移到其他节点,从而保证 Nacos 集群整体的可用性。