Topic 是业务上的一个消息分类,Partition 是它的分片,Replica 是每个 Partition 的副本。这三层关系容易背下来,但"副本会不会一起挂、一起切换"这种问题只有杀一个 Broker 才能看清楚。这次在的 3 节点集群上建了一个 6 分区、3 副本的 topic,看 Leader 分布,再 kill -9 一个 Broker,观察的故障切换范围。
命令 · shell $ kafka-topics.sh --bootstrap-server 127.0.0.1:19192 --create --topic replica-demo --partitions 6 --replication-factor 3 $ kafka-topics.sh --bootstrap-server 127.0.0.1:19192 --describe --topic replica-demo
Partition: 0 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3 Partition: 1 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1 Partition: 2 Leader: 3 Replicas: 3,1,2 Isr: 3,1,2 Partition: 3 Leader: 3 Replicas: 3,1,2 Isr: 3,1,2 Partition: 4 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3 Partition: 5 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1
创建的 6 个分区,Leader 分布在 3 个 Broker 上(broker 1 领导分区 0/4,broker 2 领导分区 1/5,broker 3 领导分区 2/3),不是全部集中在一个 Broker。这证明 Leader 是"分区级别"的角色,不是"Broker 级别"——一个 Broker 可以同时是好几个分区的 Leader,也可以只是另一些分区的 Follower。
命令 · shell $ kill -9 <broker-3-pid> # 杀掉进程,不是优雅关闭 $ kafka-topics.sh --bootstrap-server 127.0.0.1:19192,127.0.0.1:19292 --describe --topic replica-demo
Partition: 0 Leader: 1 Replicas: 1,2,3 Isr: 1,2 <- 不受影响,Leader 本来就不是 broker3 Partition: 1 Leader: 2 Replicas: 2,3,1 Isr: 2,1 <- 不受影响 Partition: 2 Leader: 1 Replicas: 3,1,2 Isr: 1,2 <- 切换:Leader 从 3 变成 1 Partition: 3 Leader: 1 Replicas: 3,1,2 Isr: 1,2 <- 切换:Leader 从 3 变成 1 Partition: 4 Leader: 1 Replicas: 1,2,3 Isr: 1,2 <- 不受影响 Partition: 5 Leader: 2 Replicas: 2,3,1 Isr: 2,1 <- 不受影响
杀掉 broker 3 后,6 个分区里只有原本由 broker 3 领导的分区 2 和分区 3 发生了 Leader 切换(都转移到了 broker 1),其余 4 个分区因为 Leader 本来就是 broker 1 或 broker 2,完全没受影响,继续正常服务。同时所有分区的 ISR 都从 3 个成员收缩到 2 个(broker 3 被移出 ISR),即使某个分区的 Leader 不是 broker 3、broker 3 只是它的 Follower,ISR 也反映了它掉线这件事。这就是 Replica/ISR 机制的边界:一个 Broker 挂掉,受直接影响(要切主)的只是它担任 Leader 的那部分分区,其他分区的可用性不受影响,因为它们的数据早就复制到了其它 Broker 上。
重启 broker 3 后,ISR 立刻恢复成 1,2,3(它作为 Follower 重新追上数据),但两个曾经切换过的分区的 Leader 没有自动切回 broker 3——观察到的是 Kafka 默认不会自动做 Leader 回迁,切走了就留在新 Leader 上,除非手动触发 Preferred Leader Election。
数据证明了 Topic/Partition/Replica 三者的分工:Topic 只是命名空间,真正承载数据和故障域的单位是 Partition;Replica 是 Partition 的副本,分布在不同 Broker 上;一个 Broker 故障只影响它担任 Leader 的那些分区,不是整个 Topic 或整个 Broker 上的所有数据都不可用——杀一次 Broker、看哪些分区切换、哪些不切换,比背概念关系图更准确。
每一步的 Leader/ISR 状态,都是本文上一节执行 kafka-topics.sh --describe 得到的原始输出,这里按分区逐个回放。