订阅更新

一台Broker凌晨挂了,消息还在不在?——副本机制和ISR详解

Kafka手册 第 6 题 约 8 分钟读完

本文目录
  1. 先说结论
  2. Leader和Follower的分工
  3. ISR机制——Kafka可靠性的核心
  4. Leader选举:Leader挂了怎么办?
  5. unclean选举:数据一致性 vs 可用性的抉择
  6. 实战踩坑:Broker下线引发的连锁反应
  7. 面试高频追问
  8. 总结

先说结论

Kafka通过多副本(Replica)保证高可用:每个Partition有多个副本分布在不同Broker上,一个是Leader(负责读写),其余是Follower(被动同步)。Leader挂了,ISR列表里的Follower会被选为新Leader,消息不丢、服务不断。

面试核心三个概念:Leader/Follower角色分工、ISR(In-Sync Replicas)同步机制、Leader选举过程。把这三个串清楚,这道题就稳了。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

在某元宇宙社交公司做实时数仓时,有一次凌晨3点收到报警:Broker-2磁盘告警,运维说需要下线维护。我第一反应就是:上面的Partition Leader会不会丢消息?Flink消费会不会中断?下游Doris实时大盘能不能扛住?这些问题的答案全在Kafka的副本机制里。面试官问这道题,就是想看你对Kafka高可用的理解有多深。

Leader和Follower的分工

角色职责数量关键细节
Leader处理所有读写请求每个Partition 1个Producer写Leader,Consumer也读Leader
Follower被动从Leader拉取数据replication.factor-1个不处理外部读写,纯备份

注意一个关键区别:Kafka的Follower不像MySQL从库那样可以分担读流量。所有读写都走Leader,Follower纯粹做数据备份。好处是不用考虑读写分离带来的延迟不一致问题,设计简单可靠。

# 查看Partition的副本分布
kafka-topics.sh --bootstrap-server broker1:9092 \
    --describe --topic gift_txn
 
# 输出示例(3 Broker + replication.factor=3):
# Topic: gift_txn  Partition: 0  Leader: 1  Replicas: 1,2,0  Isr: 1,2,0
# Topic: gift_txn  Partition: 1  Leader: 2  Replicas: 2,0,1  Isr: 2,0,1
# Topic: gift_txn  Partition: 2  Leader: 0  Replicas: 0,1,2  Isr: 0,1,2
#
# Leader分散在不同Broker上 → 负载均衡
# Replicas: 所有副本列表  Isr: 当前同步正常的副本
# 如果Isr比Replicas少,说明有Follower掉队了

ISR机制——Kafka可靠性的核心

ISR(In-Sync Replicas)是'当前和Leader保持同步的副本集合'。Follower持续从Leader拉取数据,如果拉取速度跟不上(超时或落后太多),就会被踢出ISR变成OSR(Out-of-Sync Replicas)。追上了就重新加入ISR。

# 核心参数:replica.lag.time.max.ms(默认30秒)
# Follower超过这个时间没向Leader发fetch请求
# 或fetch到的数据落后Leader超过这个时间 → 被踢出ISR
replica.lag.time.max.ms=30000
 
# ISR和acks的关系(第2篇讲过):
# acks=all等的就是ISR里所有副本的确认
# ISR越小 → acks=all的安全性越低
# 所以要配合min.insync.replicas使用
#
# 完整安全链:acks=all + min.insync.replicas=2 + replication.factor=3

Leader选举:Leader挂了怎么办?

当Leader所在的Broker宕机时,Controller(集群里负责管理的特殊Broker)会从ISR列表中选一个Follower做新Leader。流程如下:

# Leader选举过程
#
# 1. Broker-2宕机,上面有3个Partition的Leader
# 2. Controller检测到Broker-2下线(通过ZK或KRaft心跳)
# 3. 对每个受影响的Partition:
#    a. 从ISR列表中选第一个存活的副本作为新Leader
#    b. 更新元数据,通知所有Broker
#    c. Producer/Consumer自动感知新Leader
# 4. 整个选举过程通常在毫秒到秒级完成
#
# 选举策略:
# - 默认只从ISR中选(unclean.leader.election.enable=false)
# - 如果ISR为空?宁可Partition不可用也不选OSR的副本
# - 原因:OSR的数据可能落后,选它当Leader会丢数据

unclean选举:数据一致性 vs 可用性的抉择

如果ISR列表空了(所有同步副本都挂了),有两个选择:

配置行为数据安全可用性
unclean.leader.election.enable=false(默认)Partition不可用,等ISR恢复✅ 不丢数据❌ 暂时不可写
unclean.leader.election.enable=true选OSR的副本当Leader❌ 可能丢数据✅ 持续可用

我的实际选择:在元宇宙社交公司,交易类Topic(gift_txn)设false,宁可停写也不丢交易数据;行为日志Topic可以设true,保可用性优先。不同Topic不同策略,这是面试加分点。

实战踩坑:Broker下线引发的连锁反应

回到开头说的场景。凌晨Broker-2磁盘告警要下线,上面有6个Partition的Leader。我当时的处理流程:

① 先检查ISR:用kafka-topics.sh --describe确认所有受影响Partition的ISR至少还有2个副本在其他Broker上。确认OK。

② 优雅下线:不是直接kill,而是用kafka-server-stop.sh优雅关闭。Kafka会先把该Broker上的Leader转移到ISR中的其他Broker,再关闭进程。这样Consumer几乎无感知。

③ 观察Flink消费:通过Know Streaming确认Flink的Consumer Lag没有飙升,说明Leader切换成功,消费没中断。

④ 维护后重新上线:磁盘换完后启动Broker-2,它会自动从新Leader同步数据,追上后重新加入ISR。

整个过程业务无感知。这就是3副本+ISR机制的威力——任何单点故障都不影响服务。

面试高频追问

追问一:Follower怎么从Leader同步数据?

Follower主动向Leader发送Fetch请求,拉取新数据追加到自己的Log。和Consumer的消费机制类似,都是Pull模式。每个Follower维护自己的LEO(Log End Offset),当LEO追上Leader的LEO,就认为是同步的。

追问二:什么是HW(High Watermark)?

HW是ISR中所有副本都已同步到的最高offset。Consumer只能读到HW之前的消息。这保证了即使Leader切换,Consumer也不会读到还没同步到新Leader的数据。HW = min(ISR中所有副本的LEO)。

追问三:Controller是什么?怎么选的?

Controller是集群中负责管理Partition状态和Leader选举的特殊Broker。同一时间只有一个Controller。在ZK模式下通过抢注ZK临时节点选举;KRaft模式下通过Raft协议选举。Controller挂了会自动选新的。

总结

副本机制面试抓住三条线:① Leader/Follower分工(所有读写走Leader,Follower纯备份);② ISR同步机制(什么时候踢出、什么时候加回、和acks=all的关系);③ Leader选举(从ISR选、unclean选举的取舍)。如果能结合实际场景讲Broker下线时的处理流程,面试官会觉得你不只懂原理,还有生产环境的实操经验。

下一篇聊一个很多人答不好的题:Kafka能保证消息不丢不重吗?Exactly-Once到底怎么实现的?

你们生产环境Kafka的replication.factor设的几?有没有经历过Leader切换?评论区聊聊~

关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长

Kafka 面试通关手册

第11-15篇:格式选型、监控运维与数据治理

Wood聊大数据

9年大数据老兵,聊技术、聊职场、聊成长

刷题进度保存在当前浏览器