bigywater.tech
Kafka 内部原理 · 02

Topic、Partition、Replica 到底是什么关系

Topic 是业务上的一个消息分类,Partition 是它的分片,Replica 是每个 Partition 的副本。这三层关系容易背下来,但"副本会不会一起挂、一起切换"这种问题只有杀一个 Broker 才能看清楚。这次在的 3 节点集群上建了一个 6 分区、3 副本的 topic,看 Leader 分布,再 kill -9 一个 Broker,观察的故障切换范围。

验证:同一个 Topic 的不同 Partition,Leader 分散在不同 Broker 上
创建的 6 个分区,Leader 分布在 3 个 Broker 上(broker 1 领导分区 0/4,brok
验证: kill -9 一个 Broker,只有它当 Leader 的分区才切换
杀掉 broker 3 后,6 个分区里只有原本由 broker 3 领导的分区 2 和分区 3 发生了 Lea

验证:同一个 Topic 的不同 Partition,Leader 分散在不同 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。

验证: kill -9 一个 Broker,只有它当 Leader 的分区才切换

命令 · 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、看哪些分区切换、哪些不切换,比背概念关系图更准确。

分步演示:杀掉 broker3 之后,6 个分区各自发生了什么

每一步的 Leader/ISR 状态,都是本文上一节执行 kafka-topics.sh --describe 得到的原始输出,这里按分区逐个回放。

kill -9 一个 Broker,6 个分区里只有 2 个换了 Leader
这一步发生变化的分区

    参考与说明

    • 本文结果来自的 3 节点 Kafka 4.3.1 集群(KRaft 模式),topic replica-demo 设置 6 分区 3 副本;故障注入用的是 kill -9,不是 kafka-server-stop.sh 那种优雅关闭,重启后集群自愈、ISR 恢复。
    • 和《Kafka 为什么要把消息切成 Partition》一起看:那篇验证的是分区在路由和并行消费上的语义,这篇验证的是分区在副本和故障域上的语义,两者是分区这个概念的两个不同侧面。
    • 没有涉及:这次没有验证"Leader 切换期间生产者/消费者的行为"(比如 Producer 会不会短暂报错、多久能重新发现新 Leader),这部分放在 acks 和副本同步相关的文章里做。
    京ICP备2026067502号-1京公网安备11010502063487号