跳到主要内容

一致性算法

问题

分布式系统中的一致性算法有哪些?Raft 算法的原理是什么?Paxos、ZAB、Gossip 各有什么特点?

答案

一致性算法分类

算法类型应用
Paxos强一致性Google Chubby
Raft强一致性etcd、Consul、TiKV
ZAB强一致性ZooKeeper
Gossip最终一致性Redis Cluster、Cassandra

Raft 算法

Raft 是目前最易理解的强一致性共识算法,保证在多数节点(> N/2)存活时系统正常运行。

三种角色

角色职责
Leader处理所有客户端请求,管理日志复制
Follower被动接收 Leader 的日志复制
Candidate选举期间的临时角色

Leader 选举

选举流程:

  1. Follower 在 选举超时(150~300ms 随机)内未收到 Leader 心跳
  2. 转为 Candidate,任期号(Term)+1,投票给自己,并向其他节点请求投票
  3. 获得 多数票(> N/2) 后成为 Leader
  4. Leader 定期发送心跳维持地位

日志复制

日志条目只有被 多数节点 复制后才会被提交(committed)。

ZAB 协议(ZooKeeper)

ZAB(ZooKeeper Atomic Broadcast)是 ZooKeeper 的一致性协议,与 Raft 类似但有差异:

对比RaftZAB
Leader 选举任期号 + 日志新旧epoch + 事务 ID(ZXID)
日志连续性严格连续允许间隙(通过同步补齐)
新 Leader可能有未提交日志必须拥有最大 ZXID
阶段Leader 选举 + 日志复制发现 + 同步 + 广播

ZAB 的三个阶段:

  1. 发现(Discovery):选出拥有最大 ZXID 的节点作为 Leader
  2. 同步(Synchronization):Leader 将数据同步到所有 Follower
  3. 广播(Broadcast):正常处理写请求,类似 2PC(过半确认即提交)

Gossip 协议

Gossip 是一种去中心化的最终一致性协议,节点间像"谣言传播"一样扩散信息。

每个周期,每个节点随机选择几个节点交换信息,经过 O(logN)O(\log N) 轮后所有节点收到信息。

Redis Cluster 中的 Gossip

  • 每个节点每秒随机选 5 个节点,向其中最久没通信的发送 PING
  • PING/PONG 消息携带集群拓扑信息(节点状态、slot 分配)
  • 节点主观下线 → 超过半数报告 → 客观下线 → 故障转移
对比Raft/ZABGossip
一致性强一致最终一致
中心化有 Leader去中心化
收敛速度慢(O(logN)O(\log N)
网络开销较高(大量冗余消息)
容错性需要多数存活任意节点宕机不影响

常见面试问题

Q1: Raft 如何保证一致性?

答案

Raft 通过以下机制保证一致性:

  1. Leader 唯一性:同一任期内最多一个 Leader(多数票选举)
  2. 日志匹配:如果两个节点的日志在同一 index 有相同 term,则该 index 之前的所有日志相同
  3. Leader 完整性:已提交的日志一定存在于后续任期的 Leader 中
  4. 多数提交:日志被多数节点复制后才提交

所以即使 Leader 宕机,新 Leader 一定包含所有已提交的日志。

Q2: Raft 的脑裂问题怎么解决?

答案

网络分区可能导致两个子网各自选出 Leader(脑裂)。Raft 通过 多数派机制 自然解决:

  • 5 个节点分成 [A,B,C] 和 [D,E] 两组
  • [A,B,C] 有 3 个节点(多数),可以选出 Leader 并正常工作
  • [D,E] 只有 2 个节点(少数),无法选出 Leader,拒绝写入
  • 网络恢复后,[D,E] 的 Leader(旧 term)发现新 Leader 的更高 term,自动退为 Follower

Q3: ZooKeeper 的 ZAB 和 Raft 有什么区别?

答案

核心思想相似(Leader 选举 + 日志复制 + 多数提交),主要区别:

  1. 选举条件:Raft 看 term + 日志长度,ZAB 看 epoch + ZXID
  2. 新 Leader 同步:Raft 新 Leader 可能有未提交的日志需要清理;ZAB 新 Leader 先做全量同步
  3. 读一致性:ZooKeeper 默认读可能返回旧数据(Follower 读),需要 sync() 命令保证强一致读
  4. 设计目标:Raft 更通用,ZAB 专为 ZooKeeper 优化

Q4: 什么场景用 Gossip 而不是 Raft?

答案

  • Gossip:节点数很多(数百~数千)、不需要强一致性、去中心化。如 Redis Cluster(最多 1000 节点)、Cassandra
  • Raft:节点数较少(3~7 个)、需要强一致性、有 Leader 协调。如 etcd、Consul、TiKV

相关链接