分布式一致性协议
本文系统性梳理分布式一致性核心理论、四大核心协议(2PC/3PC、Paxos、Raft、ZAB)的原理、差异,并重点强化2026年必考的Raft协议核心考点,形成完整的知识体系。
一、基础理论铺垫(必考前置知识)
1.1 分布式一致性核心定义
分布式一致性,本质是在不可靠的分布式网络中,让多个节点对某个提案/数据/状态达成全局一致,同时保证容错性、安全性与活性。
核心目标:
- 原子性:操作要么全节点执行,要么全不执行,无中间状态
- 顺序性:所有节点以相同的顺序执行操作
- 安全性:永远不会提交错误的数据,已提交的数据不会丢失/回滚
- 活性:只要半数以上节点存活,系统最终能达成一致,不会永久阻塞
- 容错性:可应对节点宕机、网络延迟/丢包/分区等非恶意故障(本文所有协议均为崩溃容错CFT,不处理拜占庭恶意节点)
1.2 核心理论约束
CAP定理
分布式系统无法同时满足一致性(Consistency)、可用性(Availability)、分区容错性(Partition Tolerance),网络分区是分布式系统的必然场景,因此只能在CP(强一致、牺牲部分可用性)和AP(高可用、牺牲强一致)之间做取舍。
本文所有协议均为CP型协议,优先保证强一致性。FLP不可能原理
在异步网络中,只要存在一个可能故障的节点,就不存在完全正确的分布式一致性算法。
所有工业级一致性协议,都是在FLP原理的基础上做工程妥协(如引入超时机制、随机化、半数投票机制),在保证安全性的前提下实现活性。
二、四大核心协议 结构化拆解
2.1 2PC(两阶段提交协议)
核心定位
最早的强一致性原子提交协议,专为分布式事务设计,是分布式一致性的雏形,解决跨节点事务的原子性问题。
核心角色
- 协调者(Coordinator):全局事务的调度者,单点核心
- 参与者(Participant):执行本地事务的节点,响应协调者指令
核心原理(两阶段流程)
- 准备阶段(投票阶段)
协调者向所有参与者发送Prepare请求,参与者执行本地事务(写redo/undo日志,锁资源),但不提交,最终返回Yes(可提交)或No(不可提交)。 - 提交/中止阶段
协调者收集所有投票:- 全票
Yes:向所有参与者发送Commit请求,参与者提交本地事务,释放资源,返回ACK - 任意
No/超时:向所有参与者发送Rollback请求,参与者通过undo日志回滚,释放资源,返回ACK核心优缺点
- 全票
| 优点 | 缺点 |
|---|---|
| 原理简单,实现门槛低,可保证强一致 | 同步阻塞:所有节点在等待响应时锁资源,吞吐量极低 |
| 适用于短链路、低并发的分布式事务场景 | 单点故障:协调者宕机导致整个系统阻塞,无法恢复 |
| 数据不一致风险:Commit阶段网络异常,部分节点提交、部分未提交,出现数据分裂 | |
| 容错性极差:任意节点故障直接导致事务失败,无崩溃恢复能力 |
2.2 3PC(三阶段提交协议)
核心定位
2PC的改进版,核心解决2PC的同步阻塞和单点故障问题,降低阻塞范围,引入超时机制。
核心角色
与2PC一致:协调者、参与者
核心原理(三阶段流程)
- CanCommit阶段
协调者发送预询问请求,参与者仅检查自身资源/执行条件,不锁资源、不写日志,返回Yes/No,无阻塞风险。 - PreCommit阶段
协调者收集全票Yes后,发送预提交请求,参与者执行本地事务、写redo/undo日志、锁资源,返回ACK;若有No/超时,直接中止事务。 - DoCommit阶段
协调者收到全量ACK,发送正式提交/回滚请求,参与者执行后返回ACK;参与者超时未收到请求,会自动提交事务,解决部分阻塞问题。核心优缺点
- 改进点:拆分阶段减少阻塞范围,引入参与者超时机制,降低了永久阻塞的概率
- 缺陷:仍存在数据不一致风险(网络分区下,协调者发送Rollback,部分参与者超时自动提交),未解决单点问题,复杂度提升,工业界极少落地。
2.3 Paxos协议
核心定位
分布式一致性的理论基石,Lamport提出的基于消息传递的高容错一致性算法,有严格的数学证明,只要半数以上节点存活,就能保证数据一致,是后续所有工业级协议的理论源头。
核心角色
- Proposer(提案者):发起提案,推动达成一致
- Acceptor(接受者):对提案进行投票,决定是否接受,是决策核心
- Learner(学习者):同步已达成一致的提案,不参与投票,仅对外提供数据
核心分支拆解
Paxos分为Basic Paxos(理论基础,单值一致性)和Multi-Paxos(工程化实现,多值连续一致性),工业界落地的均为Multi-Paxos。
1. Basic Paxos 核心原理
针对单个值达成一致,核心分为两个阶段,核心规则:提案编号全局唯一且递增,只有超过半数节点接受的提案,才算最终达成一致。
- 准备阶段(Prepare)
- Proposer生成全局唯一递增的提案编号
N,向超过半数的Acceptor发送Prepare(N)请求 - Acceptor收到请求后,若
N大于其之前响应过的所有提案编号,就承诺不再接受编号小于N的提案,同时返回其已接受的最大编号的提案(若有)
- Proposer生成全局唯一递增的提案编号
- 接受阶段(Accept)
- Proposer收到超过半数的Acceptor响应后,若响应中无已接受的提案,就自定义提案值
V;若有,就采用响应中最大编号的提案值V - Proposer向超过半数的Acceptor发送
Accept(N, V)请求 - Acceptor收到请求后,若
N不小于其承诺过的最大编号,就接受该提案,返回ACK
- Proposer收到超过半数的Acceptor响应后,若响应中无已接受的提案,就自定义提案值
- 达成一致:当提案被超过半数的Acceptor接受,该提案就被最终提交,Learner同步该值。
2. Multi-Paxos 工程化改进
Basic Paxos仅能处理单个值,且存在活锁问题(多个Proposer同时发起提案,编号不断抬高,谁都无法完成提交),效率极低。Multi-Paxos做了核心改进:
- 选举出唯一的Leader,只有Leader能作为Proposer发起提案,彻底消除多Proposer的活锁问题
- 稳定Leader场景下,将两阶段简化为单阶段(跳过Prepare,直接执行Accept),大幅提升吞吐量
- 支持连续多个值的日志复制,适配分布式系统的状态机同步场景
核心优缺点
| 优点 | 缺点 |
|---|---|
| 理论严谨,安全性、活性有严格数学证明 | 极度晦涩难懂,工程化实现门槛极高 |
| 容错性极强,半数以上节点存活即可用 | 无明确的工程规范,不同实现差异大,极易出现bug |
| 是所有分布式一致性协议的理论源头 | Basic Paxos存在活锁,Multi-Paxos无统一实现标准 |
2.4 Raft协议(2026必考核心,重点强化)
核心定位
专为可理解性设计的工业级强一致性算法,在保证与Multi-Paxos同等安全性、容错性的前提下,大幅降低理解和实现难度,是目前分布式系统的首选一致性协议,工业界落地最广泛。
核心设计思路:将复杂的一致性问题,拆解为Leader选举、日志复制、安全性三个独立可解的子问题,同时配套快照压缩、成员变更两个工程化特性。
核心基础:任期(Term)机制
Term是Raft的全局逻辑时钟,是整个协议的核心骨架:
- Term是全局单调递增的整数,每一次选举对应一个新的Term
- 一个Term内,要么选出唯一的Leader,要么选举失败(Term递增,重新选举)
- 所有节点维护当前Term,任何RPC请求必须携带Term,Term更小的请求会被直接拒绝;节点发现自身Term小于其他节点,会自动更新为最新Term
核心角色(仅3种,边界清晰)
- Leader(领导者):唯一的提案者,处理客户端写请求,管理日志复制,通过心跳维持Leader身份
- Follower(跟随者):被动响应Leader和Candidate的RPC请求,不主动发起请求,同步日志、参与投票,可处理客户端读请求
- Candidate(候选者):Leader选举过程中的临时角色,由Follower超时转换而来,发起选举投票
必考核心1:Leader选举机制
触发条件
Follower在选举超时时间(随机150-300ms)内,未收到Leader的心跳包(AppendEntries RPC,兼做心跳和日志复制),就会触发选举。
随机超时时间是核心设计,避免多个Follower同时发起选举,解决选票平分问题。
选举完整流程
- Follower切换为Candidate,自增当前Term,给自己投一票,向其他节点发起
RequestVote RPC投票请求 - 其他节点收到请求后,基于投票规则进行校验,校验通过则投出赞成票
- 选举结果分支:
- Candidate收到超过半数节点的赞成票:当选为新Leader,立即向所有节点发送心跳包,宣告Leader身份,终止其他节点的选举
- 收到其他节点的合法Leader心跳:自动退回Follower状态
- 选举超时未获得过半选票:自增Term,重新发起选举
- 核心约束:一个Term内,每个节点只能投一票,先到先得
核心投票安全规则
节点只会给满足以下条件的Candidate投票:
- Candidate的Term不小于自身当前Term
- Candidate的日志比自身更新:日志的Term更大;或Term相同,日志长度更长
该规则是Raft的核心安全保证,确保当选的Leader一定包含所有已提交的日志,不会丢失已提交的数据。
必考核心2:日志复制机制
Raft的本质是基于复制状态机的一致性算法,所有节点以相同的顺序执行相同的日志指令,最终达到一致的状态。
日志条目核心结构
每个日志条目包含3个核心字段,全局唯一标识:
| 字段 | 作用 |
|---|---|
| Index(日志索引) | 全局单调递增的整数,唯一标识日志条目的位置 |
| Term(任期号) | 该条目被Leader创建时的任期号,用于校验日志合法性 |
| Command(指令) | 客户端的操作指令,最终会被执行到状态机 |
日志复制完整流程
- 客户端发送写请求给Leader,Leader将请求封装为新的日志条目,追加到本地日志(Raft仅支持日志追加,绝不修改/删除已提交的日志)
- Leader通过
AppendEntries RPC,将新日志并行发送给所有Follower - Follower收到请求后,先校验日志匹配特性:前一条日志的Index和Term与Leader发送的完全匹配,校验通过后,将日志追加到本地,返回ACK
日志匹配特性:若两个节点的日志在相同Index和Term上有相同条目,则该Index之前的所有日志完全一致。
- 当Leader收到超过半数Follower的ACK,就认为该日志条目是已提交(Committed)的,立即将该指令执行到本地状态机,给客户端返回成功响应
- Leader通过后续的心跳/日志复制请求,将已提交的日志索引
CommitIndex同步给Follower,Follower收到后,提交对应日志,执行到本地状态机
日志冲突解决
当Follower的日志与Leader冲突时,Leader会强制覆盖Follower的冲突日志:
Leader通过AppendEntries RPC,不断向前回溯,找到Follower与自己日志完全匹配的位置,删除该位置之后Follower的所有冲突日志,同步Leader的日志,最终保证Follower的日志与Leader完全一致。
必考核心3:安全性机制
Raft通过5条核心安全规则,从数学上保证永远不会出现数据不一致、已提交数据丢失的问题:
- 选举安全性:一个Term内,最多只能选出一个Leader,彻底避免脑裂
- 日志单向流动:日志只能从Leader流向Follower,Follower不能主动修改日志,Leader绝不修改/删除自己已提交的日志
- 提交限制规则:Leader只能直接提交当前Term内、已被半数节点复制的日志;对于之前Term的日志,必须和当前Term的某个日志一起被半数节点复制后,才能被提交
核心易错点:旧Term的日志即使被半数节点复制,也不会被Leader直接提交,避免旧Leader恢复后覆盖已提交的数据。
- 候选人限制规则:只有日志比半数以上节点更新的Candidate,才能当选Leader,保证已提交的日志永远不会丢失
- 状态机安全性:如果一个节点已经将某个Index的日志执行到状态机,那么其他节点绝不会在同一个Index上执行不同的指令
必考工程化特性
快照压缩(Snapshot)
解决日志无限增长的问题:节点将当前状态机的全量状态保存为快照,删除快照之前的所有日志条目,大幅降低日志存储、同步的开销,是工业界落地的必备特性。成员变更(集群配置变更)
解决集群节点增减的问题,核心避免配置变更过程中出现两个过半集群(脑裂)。- 基础方案:单节点变更,每次仅增减一个节点,保证集群半数节点的连续性,是工业界最常用的方案
- 通用方案:联合共识(Joint Consensus),两阶段变更,支持任意数量的节点同时变更
工业界应用
etcd、Consul、TiKV、RocketMQ DLedger、Elasticsearch 7.x+、MongoDB等,是目前分布式存储、配置管理、服务发现、分布式锁场景的首选协议。
2.5 ZAB协议(Zookeeper原子广播协议)
核心定位
专为Zookeeper分布式协调服务设计的崩溃容错原子广播协议,核心目标是保证Zookeeper集群的全局顺序一致性,支撑分布式锁、配置管理、服务发现等协调场景。
核心角色
- Leader:唯一处理客户端写请求,发起事务提案,全局事务排序
- Follower:处理读请求,参与Leader选举和提案投票,同步Leader数据
- Observer:只读节点,处理读请求,不参与选举和投票,仅同步数据,用于提升集群读性能,不影响写吞吐量
核心基础:ZXID事务ID
ZXID是ZAB的全局有序标识,64位整数:
- 高32位:Epoch(任期号),Leader换届后自增,与Raft的Term作用一致
- 低32位:事务序号,当前Leader任期内的事务单调递增,Leader换届后重置为0
核心原理(两大阶段)
1. 崩溃恢复阶段
触发条件:集群启动、Leader宕机、网络分区导致Leader失去过半节点联系。
- Leader选举:节点基于ZXID投票,优先投票给ZXID更大的节点(ZXID越大代表数据越新),获得过半投票的节点当选为新Leader
- 数据同步:新Leader与所有Follower进行数据对齐,补全Follower缺失的事务,回滚Follower中未提交的冲突事务,直到过半节点同步完成,恢复阶段结束。
2. 消息广播阶段
本质是简化的2PC,基于过半提交保证原子性:
- 客户端写请求发送给Leader,Leader封装为事务Proposal,生成全局唯一ZXID,向所有Follower广播Proposal
- Follower收到Proposal后,写入本地事务日志,返回ACK
- Leader收到过半Follower的ACK后,提交该事务,向所有Follower发送Commit请求,同时执行事务,给客户端返回响应
- Follower收到Commit请求后,提交对应事务,执行到本地状态机
核心特性
- 严格的全局顺序一致性:所有事务按ZXID的顺序全局执行,保证分布式协调场景的正确性
- 崩溃恢复安全保证:已提交的事务永远不会丢失,未提交的事务一定会被回滚
三、核心协议 高频对比考点
3.1 全协议核心维度对比表
| 对比维度 | 2PC/3PC | Paxos(Multi-Paxos) | Raft | ZAB |
|---|---|---|---|---|
| 核心定位 | 分布式事务原子提交协议 | 通用分布式一致性理论基础 | 通用工业级分布式一致性协议 | Zookeeper专属原子广播协议 |
| 核心角色 | 协调者、参与者 | Proposer、Acceptor、Learner | Leader、Follower、Candidate | Leader、Follower、Observer |
| 容错性 | 极差,任意节点故障导致事务失败 | 强,半数以上节点存活即可用 | 强,半数以上节点存活即可用 | 强,半数以上节点存活即可用 |
| 选举机制 | 无,单点协调者 | 无强制Leader规范,Multi-Paxos可选Leader | 强制唯一Leader,有严格的选举安全规则 | 强制唯一Leader,基于ZXID的选举规则 |
| 一致性保证 | 强一致,无崩溃恢复能力 | 强一致,理论严谨 | 强一致,有严格的安全规则保证 | 全局顺序一致性,专为协调场景优化 |
| 日志提交规则 | 全票通过才提交 | 过半接受即提交 | 当前Term日志过半复制才提交,旧Term日志需伴随当前Term日志提交 | 任意Term的日志过半复制即可直接提交 |
| 实现难度 | 极低 | 极高 | 低,规范明确 | 中等,专属场景定制 |
| 适用场景 | 短链路低并发分布式事务 | 理论场景,极少工业落地 | 通用分布式系统,存储/配置/服务发现等 | Zookeeper分布式协调服务 |
3.2 高频必考对比拆解
1. 2PC/3PC vs Raft/Paxos/ZAB 本质区别
- 2PC/3PC是原子提交协议,仅解决分布式事务的原子性问题,无容错能力、无崩溃恢复、单点核心,仅适用于封闭的事务场景
- Raft/Paxos/ZAB是通用分布式一致性协议,解决分布式系统的状态机复制问题,有强容错能力、Leader选举、崩溃恢复机制,适用于大规模分布式系统,是工业界的主流选择
2. Raft vs Paxos 核心区别
| 维度 | Raft | Paxos |
|---|---|---|
| 设计目标 | 可理解性优先,工程化落地为核心 | 理论严谨性优先,无工程化约束 |
| 角色划分 | 边界清晰,仅3种角色,职责固定 | 角色灵活,无强制职责划分 |
| Leader机制 | 强制唯一Leader,是协议的核心,有严格的选举规则 | Leader是Multi-Paxos的优化选项,无强制选举规范 |
| 日志规范 | 有严格的日志匹配特性,Leader强制覆盖Follower冲突日志,规范明确 | 无明确的日志复制、冲突解决规范,不同实现差异极大 |
| 安全性 | 安全规则明确,可直接落地 | 仅理论安全,工程化需自行补充大量安全逻辑 |
3. Raft vs ZAB 核心区别(高频考点)
| 维度 | Raft | ZAB |
|---|---|---|
| 设计目标 | 通用状态机复制,适配全场景分布式系统 | 专为分布式协调服务设计,核心保证全局事务顺序一致性 |
| 序号机制 | 日志Index全局单调递增,Leader换届不重置 | ZXID低32位事务序号,Leader换届后重置为0 |
| 日志提交规则 | 不能直接提交旧Term的日志,需伴随当前Term日志提交 | 可直接提交旧Epoch的、已过半复制的日志 |
| 读一致性 | 默认Follower读可能读到旧数据,线性一致性读需Leader/ReadIndex/租约机制 | 默认提供顺序一致性读,线性一致性读需主动调用sync() |
| 角色设计 | 无只读角色,Follower必须参与投票 | 新增Observer只读角色,不参与投票,可无损提升读性能 |
| 适用范围 | 全场景通用,工业界落地最广 | 仅适配Zookeeper协调场景,无其他大规模落地 |
四、2026年Raft协议 必考考点清单
基础必背考点
- Raft的三大核心子问题:Leader选举、日志复制、安全性
- Raft的三大角色、任期Term的核心作用
- Raft的日志条目结构、日志匹配特性
- Raft的已提交定义、过半投票机制的核心作用
高频核心考点
- Leader选举的触发条件、完整流程、随机超时时间的作用
- Raft的投票安全规则,为什么能保证新Leader一定包含所有已提交的日志
- 日志复制的完整流程,Follower日志冲突的解决方式
- Raft的提交限制规则,为什么不能直接提交旧Term的日志
- Raft如何解决网络分区、脑裂问题(任期机制、过半投票、心跳校验)
- 快照压缩的核心作用、实现逻辑
- 集群成员变更的核心风险,单节点变更方案的原理
- Raft线性一致性读的实现方案(Leader读、ReadIndex、LeaseRead)
- Raft与Paxos、ZAB的核心区别
易错考点
- ❌ 错误:Raft的Leader可以修改已提交的日志
✅ 正确:Raft仅支持日志追加,Leader绝不修改/删除已提交的日志 - ❌ 错误:日志被过半复制,就一定会被提交
✅ 正确:只有当前Term的日志被过半复制,才会被直接提交;旧Term的日志需伴随当前Term的日志一起被过半复制,才能被提交 - ❌ 错误:节点可以给日志比自己旧的Candidate投票
✅ 正确:节点只会给日志比自己更新的Candidate投票,保证选举安全性 - ❌ 错误:旧Leader恢复后,会覆盖新Leader的日志
✅ 正确:旧Leader恢复后,发现自身Term更小,会自动转为Follower,同步新Leader的日志,不会修改已提交的数据
五、工业界选型总结
- 2PC/3PC:仅适用于短链路、低并发的分布式事务场景(如跨库事务),高可用分布式系统不推荐使用
- Paxos:仅适用于对理论严谨性要求极高、有充足技术实力自研的场景,目前已基本被Raft替代
- Raft:通用分布式一致性场景的首选方案,适配分布式存储、配置管理、服务发现、分布式锁等绝大多数场景,生态成熟、实现简单、工业界验证充分
- ZAB:仅适用于Zookeeper分布式协调服务,其他场景无落地价值