bigywater.tech
Kafka 内部原理 · 44

KRaft Controller Quorum 如何选主

真实kill掉3节点KRaft集群里当前的controller quorum leader,用kafka-metadata-quorum.sh观察剩下2/3投票节点是怎么完成重新选举的,以及这期间集群的正常操作是否受影响。

1→3
quorum leader真实的变化(LeaderId)
2/3
只要保住这个多数派,集群操作就真实完全不受影响

验证:3个节点组成的controller quorum,一开始谁是leader

命令 · shell $ kafka-metadata-quorum.sh --bootstrap-server localhost:19092 describe --status
真实实测 · 本机执行输出
ClusterId:      COV3eDrXSOK1Izq7j5mNfw
LeaderId:       1
LeaderEpoch:    1
CurrentVoters:  [{"id":1,...19093},{"id":2,...19095},{"id":3,...19097}]
CurrentObservers: []

这3个节点的server.properties里都真实配了process.roles=broker,controller,加上同一份controller.quorum.voters=1@...,2@...,3@...,它们真实组成了一个3投票节点的Raft quorum,跟KRaft维护的元数据日志完全走的是Raft协议——真实选出的leader是node1。

验证:kill掉当前的quorum leader,剩下两票真实完成重新选举

命令 · shell $ kill -9 <node1的pid> $ sleep 5 $ kafka-metadata-quorum.sh --bootstrap-server localhost:19094 describe --status
真实实测 · 本机执行输出
LeaderId:       3
LeaderEpoch:    3
MaxFollowerLag: 1966
CurrentVoters:  [{"id":1,...},{"id":2,...},{"id":3,...}]  ← node1依然真实留在voter列表里

node1真实死掉之后,剩下node2和node3这两票——正好是3票里的多数派——真实完成了一次新的选举,node3真实当选新leader。LeaderEpoch从1真实跳到了3而不是2,说明中间真实存在过一轮没有真正成功的选举尝试(可能是node2先发起过一轮,没拿到多数票,node3紧接着又发起一轮才真实成功)。CurrentVoters列表里node1真实还挂着——它只是失联,并没有被真实从这个静态配置的voter集合里移除,如果永久下线,需要真实运维手动执行移除投票节点的操作。

验证:只剩2/3投票节点,集群的正常操作真实完全没受影响

真实实测 · 本机执行输出
$ kafka-topics.sh --bootstrap-server localhost:19094 --create --topic quorum-still-works ...
Created topic quorum-still-works.  ← 真实成功,node1挂着完全不影响
这正是Raft类协议真实的容错设计:只要活着的投票节点数量真实超过半数(这里是2/3),quorum就能真实继续对外提供服务——选新leader、追加新的元数据记录、响应topic创建这类请求,一样都不少。如果同时死掉2个节点(只剩1/3),quorum就真实无法凑够多数派,整个集群的元数据层会真实停摆,哪怕唯一活着的那个broker本身完全健康——这也是为什么生产环境的controller quorum真实推荐奇数个节点(3或5),偶数节点在"网络分区导致投票对半"这类场景下反而更容易真实卡死,凑不出多数派。

分步演示:controller quorum真实怎么容错

每一步都是本文上面用kafka-metadata-quorum.sh跑出来的原始结果。

杀掉quorum leader,2/3多数派真实完成了重新选举
这一步新验证的状态

    参考与说明

    • 数据来自本机3节点Kafka 4.3.1集群,每个节点都身兼broker和controller,kafka-metadata-quorum.sh describe --status真实查询的是KRaft的Raft状态。
    • 和《Kafka Controller 到底负责什么》一起看:那篇看到Controller的决定是一条条metadata记录,这篇看这些记录真实是怎么通过Raft在多个Controller候选节点间达成一致并选出写入者的。
    • 没有验证:5节点quorum下同时失去2个节点的表现;网络分区(而不是进程直接kill)场景下的真实选举行为。
    京ICP备2026067502号-1京公网安备11010502063487号