深色模式
Kafka 分区与副本
摘要:分区决定 Kafka 的并行度上限,副本决定容灾能力。本文给出分区数的估算方法、副本与 ISR 的工作机制、关键可靠性参数配置,以及分区扩容与副本重分配的实操命令。
适用环境
bash
# 已有 Topic 的分区与副本现状
/opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --describe
# 集群 broker 数量(决定副本因子上限)
/opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092 \
--version 2>/dev/null | grep -c '^localhost'1
2
3
4
5
6
2
3
4
5
6
操作步骤
1. 估算分区数
bash
# 经验公式:目标吞吐 / 单分区实际吞吐
# 生产端单分区吞吐(MB/s)
/opt/kafka/bin/kafka-producer-perf-test.sh \
--topic perf-test --num-records 1000000 --record-size 1024 \
--throughput -1 --producer-props bootstrap.servers=localhost:9092
# 消费端单分区吞吐
/opt/kafka/bin/kafka-consumer-perf-test.sh \
--bootstrap-server localhost:9092 --topic perf-test --messages 10000001
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
分区数 ≈ max(目标生产吞吐/单分区生产吞吐, 目标消费吞吐/单分区消费吞吐),再向上取整到 broker 数的整数倍,保证分区均匀分布。
2. 创建时指定分区与副本
bash
/opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 \
--create --topic order-events \
--partitions 12 --replication-factor 3 \
--config min.insync.replicas=2 \
--config retention.ms=604800000 # 保留 7 天1
2
3
4
5
2
3
4
5
3. 配置可靠性关键参数
properties
# broker 侧
default.replication.factor=3
min.insync.replicas=2 # 至少 2 个副本同步才允许写入
unclean.leader.election.enable=false # 禁止非 ISR 副本成为 leader,避免丢数据
auto.leader.rebalance.enable=true
# 生产端
acks=all # 等所有 ISR 副本确认
enable.idempotence=true # 开启幂等,避免重试产生重复消息1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
4. 理解 ISR 与副本状态
bash
/opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 \
--describe --topic order-events | head -5
# Leader: 负责读写的副本编号
# Replicas: 全部副本所在 broker
# Isr: 与 leader 保持同步的副本(落后过多会被踢出)1
2
3
4
5
2
3
4
5
5. 分区扩容
bash
/opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 \
--alter --topic order-events --partitions 241
2
2
6. 副本重分配(节点扩容后把分区迁过去)
bash
cat > /tmp/reassign.json <<'EOF'
{"version":1,"partitions":[
{"topic":"order-events","partition":0,"replicas":[1,2,3]},
{"topic":"order-events","partition":1,"replicas":[2,3,4]}
]}
EOF
/opt/kafka/bin/kafka-reassign-partitions.sh --bootstrap-server localhost:9092 \
--reassignment-json-file /tmp/reassign.json --execute
/opt/kafka/bin/kafka-reassign-partitions.sh --bootstrap-server localhost:9092 \
--reassignment-json-file /tmp/reassign.json --verify1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
DANGER
分区数只能增加不能减少,且扩容会改变 key 的分区映射。依赖 key 保序的业务必须先确认下游能容忍短暂乱序,否则应新建 Topic 迁移而不是原地扩容。
验证
bash
# 1) 分区均匀分布(每个 broker 上的 leader 数接近)
/opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --describe \
--topic order-events | awk '{print $4}' | sort | uniq -c
# 2) 无分区处于 UnderReplicated 状态
/opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 \
--describe --under-replicated-partitions
# 3) 无 leader 缺失
/opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 \
--describe --unavailable-partitions
# 4) 压测确认吞吐达标
/opt/kafka/bin/kafka-producer-perf-test.sh --topic order-events \
--num-records 500000 --record-size 1024 --throughput -1 \
--producer-props bootstrap.servers=localhost:9092 acks=all1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
常见坑
WARNING
分区不是越多越好。分区过多会显著增加文件句柄、内存占用和 leader 选举时间,集群恢复变慢。一般单 broker 上分区总数控制在数千级别以内。
WARNING
replication-factor=1 的 Topic 在 broker 宕机时直接不可用。生产环境至少 3 副本 + min.insync.replicas=2。
DANGER
unclean.leader.election.enable=true 会让落后很多的副本成为 leader,代价是丢失它落后的那部分消息。除非可用性优先于一致性,否则保持 false。