一文搞懂Raft与ZAB区别、选举流程、一致性哈希、2PC vs TCC、AP vs CP、Kafka KRaft
📖 作者介绍
大家好,我是 CodeStats。
一个在底层技术上“考古”了四年的硬核爱好者,也是 WWAIC(全周项目AI编程) 范式的提出者和实践者。我曾手写过一个完整的 Java Web 框架(从 IoC 容器到嵌入式 Tomcat,代码全开源),也喜欢用通俗的语言拆解 CPU、JVM、操作系统的运行本质。
💡 我的技术信条:所有高深的技术,最后都能用大白话讲清楚。如果讲不清楚,说明还没真正理解。
🎯 通过本文你能获得什么
分布式系统是一个庞杂的技术领域,初学者往往被各种协议、算法和架构概念搞得晕头转向。本文聚焦 6个最核心、面试最高频 的分布式系统问题,从原理到对比,从理论到实践,帮你建立清晰的知识脉络:
Raft vs ZAB —— 两大共识算法,到底差在哪?
Raft选举流程 —— Leader是怎么选出来的?
一致性哈希 —— 环形结构如何搞定扩缩容?
2PC vs TCC —— 分布式事务,强一致还是补偿?
AP vs CP —— CAP定理下,你的系统该选哪边?
Kafka KRaft —— 为什么要踢掉ZooKeeper自己上?
📑 目录
-
一、Raft和ZAB算法核心区别对比
-
二、Raft算法选举流程
-
三、一致性哈希解决分布式缓存扩缩容问题
-
四、2PC和TCC区别对比
-
五、AP系统和CP系统区别
-
六、Kafka为什么选择KRaft替换ZK
一、Raft和ZAB算法核心区别对比
💡 核心观点
Raft是“通用螺丝刀”,哪里都能用;ZAB是“定制开瓶器”,专为ZooKeeper服务。两者都能拧螺丝,但设计哲学完全不同。
1.1 设计目标不同
| 定位 | 通用共识算法 | ZooKeeper专属协议 |
| 设计理念 | 易于理解、易于工程实现 | 为ZK的特定场景定制 |
| 典型应用 | Etcd、TiKV、Consul、KRaft | ZooKeeper |
1.2 核心差异
① 选举逻辑不同
-
Raft:比较 任期号(Term) 和 日志索引,谁更新谁当选
-
ZAB:比较 ZXID(事务ID) 和 SID(服务器ID),数据越新越优先
② 数据同步方向不同
-
Raft:Leader → Follower,单向复制
-
ZAB:Discovery(发现) + Synchronization(同步),双向确认后复制
③ 未提交事务处理不同
-
Raft:只有已提交的日志才会被新Leader保留
-
ZAB:旧Leader的未提交事务会被积极处理(确保不丢失)
1.3 一句话总结
Raft是“通用版”,强调易理解;ZAB是“定制版”,强调工程折中。
二、Raft算法选举流程
💡 核心观点
Raft选举像“班长竞选”——谁先举手(超时)谁发起竞选,谁能拉到半数以上选票谁当选,然后靠“打铃”(心跳)维持权威。
2.1 三种角色
| Follower(跟随者) | 被动接收指令,初始状态 |
| Candidate(候选人) | 超时后发起竞选 |
| Leader(领导者) | 处理请求,复制日志 |
2.2 选举四步走
第一步:Follower 超时 → 变成 Candidate
-
每个Follower有随机的超时时间(150-300ms)
-
超时后 → 任期号 Term + 1 → 投自己一票 → 发送投票请求
第二步:其他节点投票
-
每个任期只能投一票
-
投票规则:任期号高的优先,任期相同比日志完整性
第三步:统计选票
-
获得 超过半数(N/2 + 1) 的选票 → 当选Leader
-
未过半 → 等待下一轮
第四步:发送心跳维持地位
-
当选后立即发送心跳,防止别人再次超时发起选举
2.3 图解流程
text
所有节点启动 → 都是Follower
↓
选举计时器超时(随机)
↓
Follower → Candidate(任期+1)
↓
发送投票请求(RequestVote RPC)
↓
┌──┴──┐
↓ ↓
超过半数票 未超过半数票
↓ ↓
当选Leader 等待下一轮
↓
发送心跳维持领导地位
三、一致性哈希解决分布式缓存扩缩容问题
💡 核心观点
传统哈希取模是“搬家式扩容”——加一台机器,所有数据都要搬家。一致性哈希是“微创式扩容”——加一台机器,只影响它旁边的一小段数据。
3.1 传统取模的痛点
分布式缓存中,如果用 hash(key) % n 决定数据存到哪台机器:
-
加一台机器:n 变成 n+1,几乎所有数据的哈希值都变了
-
结果:大量缓存失效 → 数据库压力暴增 → 可能雪崩
3.2 一致性哈希原理
把哈希值(0 ~ 2^32-1)组织成一个环
-
存节点:把每台服务器的IP/主机名哈希后放在环上
-
存数据:计算Key的哈希值,在环上顺时针找第一个节点
增删节点的影响极小:
-
新增节点:只影响该节点到下一个节点之间的数据
-
删除节点:只影响被删节点上的数据,迁移给下一个节点
3.3 虚拟节点:解决负载不均
物理节点少时,在环上可能分布不均 → 数据倾斜。
解决方案:为每个物理节点创建多个虚拟节点(如 NodeA#1 ~ NodeA#100),让它们均匀分布在环上 → 负载均衡。
3.4 一句话总结
一致性哈希 = 哈希环 + 顺时针寻址 + 虚拟节点,是分布式缓存的标配算法。
四、2PC和TCC区别对比
💡 核心观点
2PC是“层层审批”,所有参与者都同意才能提交,强一致但阻塞。TCC是“先占座再付款”,灵活但需要你自己写补偿逻辑。
4.1 2PC(两阶段提交)
两个阶段:
| 准备阶段 | 问所有人:“能提交吗?” | 执行事务但不提交,返回YES/NO |
| 提交/回滚 | 全部YES就提交,有NO就回滚 | 协调者发最终指令 |
-
✅ 优点:保证强一致性
-
❌ 缺点:阻塞(资源锁定)、单点故障(协调者挂了全完蛋)
4.2 TCC(Try-Confirm-Cancel)
三个阶段:
| Try(尝试) | 预留资源 | 检查并锁定业务资源 |
| Confirm(确认) | 正式提交 | 所有Try成功,执行提交 |
| Cancel(取消) | 释放资源 | 有Try失败,回滚释放 |
-
✅ 优点:锁粒度小、性能好、不阻塞
-
❌ 缺点:需要自己实现补偿逻辑,对业务侵入性强
4.3 核心对比
| 实现层面 | 数据库层 | 应用层 |
| 资源锁定 | 锁整个资源 | 锁粒度小 |
| 一致性 | 强一致性 | 最终一致性 |
| 性能 | 较低(阻塞) | 较高 |
| 开发复杂度 | 低(DB支持) | 高(自己写补偿) |
| 适用场景 | 金融核心交易 | 电商订单、库存扣减 |
五、AP系统和CP系统区别
💡 核心观点
CP系统是“宁可不服务,也不能出错”(银行转账);AP系统是“永远在线,偶尔出错也无妨”(微博点赞)。没有好坏,看业务要什么。
5.1 CAP定理
分布式系统无法同时满足:
-
C(一致性):所有节点数据一致
-
A(可用性):每个请求都能收到响应
-
P(分区容错):网络故障时继续运行
网络分区(P)不可避免 → 只能在 C 和 A 之间二选一。
5.2 CP系统
| 特点 | 网络分区时可能不可用,但保证数据一致 |
| 典型代表 | ZooKeeper、HBase |
| 适用场景 | 银行交易、分布式锁 |
5.3 AP系统
| 特点 | 网络分区时可能数据不一致,但系统始终可用 |
| 典型代表 | Cassandra、Eureka |
| 适用场景 | 社交媒体、CDN、点赞评论 |
5.4 重要提醒
⚠️ CAP的粒度是数据,不是系统。同一个系统里,敏感数据选CP,非敏感数据选AP。比如用户系统:账号密码数据必须CP,用户昵称可以AP。
六、Kafka为什么选择KRaft替换ZK
💡 核心观点
ZooKeeper像“外部物业公司”——Kafka的一举一动都要等物业审批。KRaft把物业公司“收购”了,所有决策自己说了算,效率直接翻倍。
6.1 传统ZooKeeper模式的痛点
① 运维复杂
-
需要同时维护 Kafka + ZooKeeper 两套集群
-
运维人员必须精通两套系统
② 性能瓶颈
-
ZooKeeper写入需要过半节点投票,延迟高
-
分区数超 20万 时成为瓶颈
③ 故障恢复慢
-
Controller宕机,新Controller需全量加载元数据
-
20万分区时恢复需要几分钟甚至十几分钟
④ 一致性风险
-
Kafka和ZooKeeper各自维护状态,可能数据不一致
6.2 KRaft的核心改进
| 架构复杂度 | 需额外维护ZK集群 | 无外部依赖,一套搞定 |
| 分区上限 | ~20万 | ~200万(提升10倍) |
| 故障恢复 | 分钟级 | 秒级(热备切换) |
| 元数据操作 | 请求-响应模式 | 事件流模式(日志追加) |
| 一致性 | ZAB协议 | Raft协议(更高效) |
6.3 为什么KRaft更快?
① 存储引擎变了:ZooKeeper用树状ZNode(随机写)→ KRaft用顺序追加日志(顺序写,快3-4个数量级)
② 通知机制变了:ZooKeeper用 Watch(通知-拉取) → KRaft用 事件流(直接推送消费)
③ 故障恢复变了:ZooKeeper是 冷启动全量加载 → KRaft是 热备增量追赶
6.4 版本演进
| Kafka 2.8.0 | KRaft实验阶段 |
| Kafka 3.3.0 | KRaft 生产可用 |
| Kafka 4.0+ | KRaft 成为默认模式,不再支持ZooKeeper |
💡 建议:新集群直接用 Kafka 4.0+ KRaft模式,别再走老路了。
📝 总结
| Raft vs ZAB | Raft通用易懂,ZAB专为ZK定制 |
| Raft选举 | 超时发起 → 投票过半 → 心跳维持 |
| 一致性哈希 | 哈希环 + 虚拟节点,增删只影响邻近数据 |
| 2PC vs TCC | 2PC强一致但阻塞,TCC高并发但需写补偿 |
| AP vs CP | 敏感数据选CP,非敏感选AP |
| Kafka KRaft | 用Raft替代ZK,分区上限从20万到200万 |
觉得有用?点赞、收藏、转发走一波~ 有问题评论区见!👇



