副本机制
定义与作用
副本(Replica)是 Partition 的冗余拷贝。Kafka 为每个 Partition 创建多个副本,分布在不同的 Broker 上。副本机制是 Kafka 实现高可用和数据不丢失的基石:当 Leader 副本所在的 Broker 宕机,Follower 副本可以接替成为新 Leader。
每个 Partition 的副本中,只有一个是 Leader(接收读写),其余是 Follower(只从 Leader 同步数据)。
核心原理
副本角色模型
角色对比:
| Leader | Follower | |
|---|---|---|
| 读写请求 | 处理全部 | 不处理 |
| 数据来源 | Producer 直接写入 | 从 Leader fetch |
| Producer 连接 | 必须 | 不需要 |
| Consumer 连接 | 必须 | 不需要(Kafka 2.4+ 可读 Follower) |
| 数量 | 每分区 1 个 | N-1 个 |
副本分布策略
Kafka 的副本分配遵循以下约束,确保高可用:
假设 3 Broker,Topic `demo` 有 3 分区,3 副本
Partition 0: [Leader: B1, Follower: B2, B3]
Partition 1: [Leader: B2, Follower: B3, B1]
Partition 2: [Leader: B3, Follower: B1, B2]
→ 每台 Broker 既是某些分区的 Leader,也是其他分区的 Follower
→ 任意一台宕机,其他 Broker 上有 Follower 可以接替
副本同步流程
完整示例
示例一:创建多副本 Topic
场景:3 Broker 集群,创建 3 副本的 Topic,验证副本分布。
# 创建 3 分区、3 副本的 Topic
bin/kafka-topics.sh --create --topic orders-replicated \
--partitions 3 --replication-factor 3 \
--bootstrap-server localhost:9092
# 查看副本分布
bin/kafka-topics.sh --describe --topic orders-replicated \
--bootstrap-server localhost:9092
输出:
Topic: orders-replicated Partition: 0 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3
Topic: orders-replicated Partition: 1 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1
Topic: orders-replicated Partition: 2 Leader: 3 Replicas: 3,1,2 Isr: 3,1,2
分析:3 个分区的 Leader 均匀分布在 3 台 Broker 上(负载均衡),每个 Leader 所在行第一个 Replicas 数字等于 Leader 数字(说明 Preferred Leader 分配正确)。
示例二:副本因子不足的错误
场景:2 Broker 集群尝试创建 3 副本的 Topic。
bin/kafka-topics.sh --create --topic test-rf3 \
--partitions 3 --replication-factor 3 \
--bootstrap-server localhost:9092
输出:
Error: Replication factor: 3 larger than available brokers: 2.
规则:replication-factor ≤ 集群 Broker 数量。
易错场景
易错 1:误认为 Follower 可以分担读负载
场景:高读 QPS 场景下,增加副本数期望提升读性能。
事实:Kafka(3.x 之前)只有 Leader 处理读请求。增加副本数不会提升读性能,反而增加同步开销。Kafka 2.4+ 引入 rack-aware 消费者可读 Follower(需 client.rack 配置),但默认不开启。
正确做法:通过增加分区数来提升读并行度。
易错 2:副本数设得太高
场景:Topic 有 50 个分区,每个分区 5 个副本。
后果:总共 250 个副本需要维护。大量网络带宽用于副本复制,Broker 内存压力大。
经验法则:
- 一般生产环境:3 个副本
- 银行/支付等极高可靠性:5 个副本
- 日志/监控等可容忍丢失:1-2 个副本
面试高频考点
Q:Kafka 的副本和分布式存储(如 HDFS)的副本有什么本质区别?
A:
- Kafka:每个 Partition 只有一个活跃副本(Leader),Follower 是被动同步,从不接受写入。这是为了确保每个 Partition 内的消息是完全有序的。
- HDFS:任意副本都可读,写入经 Leader Pipeline 同步到多个 DataNode。因为 HDFS 文件没有"分区内消息顺序"的概念。
Kafka 的选择牺牲了部分读吞吐(需要从 Leader 读),换取了分区内的绝对有序性。