Kafka 有几种选举过程?

#中间件#面试八股

Kafka 有几种选举过程?

结论:Kafka 里有三种性质完全不同的"选举"——Controller 选举(集群管理节点,ZK 模式下靠抢占临时节点、KRaft 模式下靠 Raft)、分区 Leader 选举(Controller 从 ISR 里挑一个副本)、消费组 Leader 选举(组协调器挑一个消费者负责分配方案)。面试里问"几种选举",要能分别说清触发条件、参与者与算法。

一、三种选举对比

选举触发条件参与者算法影响范围
Controller 选举Controller 所在 Broker 宕机所有 BrokerZK:抢占 /controller 临时节点;KRaft:Raft 多数派整个集群的元数据管理暂停
分区 Leader 选举Leader 副本所在 Broker 下线,或副本被踢出 ISRISR 内副本(可配置含非 ISR)Controller 从 ISR 列表取第一个可用副本仅该分区短暂不可读写
消费组 Leader 选举组内 Leader 消费者下线或新成员加入组内所有消费者组协调器指定第一个加入的成员触发一次重平衡,全组暂停消费

二、Controller 选举

ZK 模式:
  Broker 启动 ──> 尝试创建 /controller 临时节点
      ├─ 创建成功 → 成为 Controller,并写入自己的 brokerId
      └─ 创建失败 → 监听该节点,等待旧 Controller 会话过期后重新抢占

KRaft 模式:
  Controller 节点组成 Raft 组(controller.quorum.voters)
      └─ 多数派选出一个 Active Controller,其余为 Follower
          └─ 元数据变更写入 __cluster_metadata 日志,按 Raft 复制

ZK 模式靠临时节点(Ephemeral Node)+ 会话超时避免脑裂,但切换要等会话过期,通常是秒级到十几秒;KRaft 用 Raft 的 term 与多数派,切换在亚秒级,且不再依赖外部组件。

三、分区 Leader 选举

Controller 监听 Broker 变化
   │
   ├─ Broker-2 下线 → 它上面的 Leader 分区 P0、P3 需要重新选主
   │
   ├─ 读取每个分区的 ISR 列表(如 P0: [1,2,3])
   │
   ├─ 从 ISR 中选一个存活副本(通常是列表第一个)作为新 Leader
   │
   ├─ 更新元数据并广播给所有 Broker
   │
   └─ 若 ISR 为空 → 检查 unclean.leader.election.enable
         ├─ false(推荐):分区保持不可用,等原 Leader 恢复
         └─ true:从非 ISR 副本中选主,可用性恢复但会丢数据

unclean.leader.election.enable=true 是"用数据换可用"的开关:选出的副本可能缺一段消息,且新 Leader 一旦写入,旧 Leader 回来后会截断日志(Log Truncation),那段消息就永久丢了。

四、消费组 Leader 选举

消费组的 Leader 并不"管理"其他消费者,它只负责计算分区分配方案:

组协调器(GroupCoordinator)        Consumer Leader          其他成员
      │ 收到 JoinGroup                   │                     │
      ├─────────────────────────────────>│                     │
      │  指定第一个加入者为 Leader         │                     │
      │                                  │ 计算分配:c1→P0,P1   │
      │                                  │        c2→P2,P3      │
      │<───────── SyncGroup(分配方案) ─────┤                     │
      ├──────────────────────────────────┼────────────────────>│
      │                                  │                     │
      └─ 各成员按方案开始消费 ────────────────────────────────────>

分配策略(Range、RoundRobin、Sticky、CooperativeSticky)会影响重平衡的代价,CooperativeSticky 是增量式重平衡,可以避免全量停止消费。

五、观察与配置

# 查看分区 Leader/ISR 状态
kafka-topics.sh --bootstrap-server 10.0.0.31:9092 --describe --topic order

# KRaft 下查看 Controller 状态与 quorum
kafka-metadata-quorum.sh --bootstrap-server 10.0.0.31:9092 describe --status

# 触发一次 Preferred Leader 选举(把 Leader 迁回首选副本)
kafka-leader-election.sh --bootstrap-server 10.0.0.31:9092 \
  --election-type preferred --all-topic-partitions

六、常见追问

  • 为什么优先选 ISR 里的副本? ISR 是与 Leader 同步的副本,选它不会丢已提交的消息;非 ISR 副本落后,选它就意味着丢数据。
  • Controller 选举期间集群还能读写吗? 已有分区的读写不受影响,但不能创建 Topic、不能选举新 Leader,故障分区的恢复会被推迟。
  • 消费者 Leader 挂了会怎样? 组协调器重新选一个 Leader 并触发重平衡,整个组在重平衡期间暂停消费,因此要尽量避免频繁成员变更。
  • KRaft 里还有 Controller 选举吗? 有,但变成 Raft 组内的选主,不再是抢 ZK 节点;Broker 与 Controller 可以合设,也可以分离部署。

小结

  • 三种选举分别对应:集群管理节点、分区主副本、消费组分配者。
  • Controller 选举影响元数据操作,分区选举只影响单个分区,消费组选举影响整组消费。
  • 分区选举优先 ISR,unclean 开关决定可用性与数据安全的取舍。
  • KRaft 用 Raft 取代 ZK 抢占,切换更快、依赖更少,是当前主流部署方式。
笔记加载中…