10.1.2 主题、分区与副本机制
主题(Topic)是业务消息的逻辑分类;分区(Partition)是主题的物理切分单元;副本(Replica)提供容错与高可用。三者共同决定吞吐、扩展性与可靠性。
原理草图(主题-分区-副本)
安装与准备(仅本节命令示例所需)
# 假设已安装 Kafka,示例使用二进制包
tar -xf kafka_2.13-3.6.0.tgz
cd kafka_2.13-3.6.0
# 使用 KRaft 单机快速启动(仅演示)
bin/kafka-storage.sh random-uuid > /tmp/kafka-uuid
bin/kafka-storage.sh format -t "$(cat /tmp/kafka-uuid)" -c config/kraft/server.properties
bin/kafka-server-start.sh -daemon config/kraft/server.properties
# 验证服务端口
ss -lntp | grep 9092
主题设计要点
- 主题与业务边界一致,避免“大而全”导致治理困难。
- 分区数决定并行度;副本数决定容错能力与成本。
- 选择合适的保留策略与压缩策略(Log Compaction)。
分区机制示例(创建与路由)
# 创建主题:3 分区、3 副本
bin/kafka-topics.sh --bootstrap-server localhost:9092 \
--create --topic orders --partitions 3 --replication-factor 3
# 查看主题详情(含分区、副本、Leader、ISR)
bin/kafka-topics.sh --bootstrap-server localhost:9092 \
--describe --topic orders
# 生产消息:指定 key,保证相同 key 落同一分区
bin/kafka-console-producer.sh --bootstrap-server localhost:9092 \
--topic orders --property "parse.key=true" --property "key.separator=:"
# 输入示例:
# user_1001:{"order_id":1,"amount":99}
# user_1001:{"order_id":2,"amount":49}
# user_2001:{"order_id":3,"amount":20}
副本机制示例(可靠性配置)
# 修改主题参数:最小同步副本数
bin/kafka-configs.sh --bootstrap-server localhost:9092 \
--alter --entity-type topics --entity-name orders \
--add-config min.insync.replicas=2
# 生产端建议:
# acks=all + retry + 幂等(enable.idempotence=true)
cat > /tmp/producer.properties <<'EOF'
acks=all
enable.idempotence=true
retries=10
linger.ms=5
batch.size=32768
EOF
bin/kafka-console-producer.sh --bootstrap-server localhost:9092 \
--topic orders --producer.config /tmp/producer.properties
典型配置与权衡
- 高吞吐:提高分区数,适度降低副本数(需更强磁盘与网络)。
- 高可靠:副本数≥3,配合 acks=all 与 min.insync.replicas。
- 有序性:按业务 Key 分区,避免频繁扩容改变 Key 映射。
常见问题与排查(含命令解释)
- 分区不均衡(热点 Key)
```bash
# 查看各分区的消息量(估算),以及消费组分配
bin/kafka-run-class.sh kafka.tools.GetOffsetShell \
--bootstrap-server localhost:9092 --topic orders
bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
--describe --group groupA
```
解释:GetOffsetShell 输出各分区末端 offset,差异过大说明数据倾斜。
-
副本频繁掉线(ISR 缩减)
bash # 查看 ISR bin/kafka-topics.sh --bootstrap-server localhost:9092 \ --describe --topic orders
解释:ISR 列表缩短说明部分副本跟不上或离线,检查 Broker 日志与磁盘 IO。 -
扩容后顺序变化
bash # 增加分区(会影响 key->partition 映射) bin/kafka-topics.sh --bootstrap-server localhost:9092 \ --alter --topic orders --partitions 6
解释:扩容会改变哈希分布,依赖全局顺序的业务需重构或使用单分区。
练习
1. 创建主题 payments,3 分区 2 副本,设置 min.insync.replicas=2,并验证 ISR。
2. 发送带 key 的消息,观察同一 key 是否进入同一分区。
3. 扩容主题分区数并比较扩容前后的分区分布变化。
4. 模拟副本落后:限制某 Broker 的磁盘或停机,观察 ISR 变化并恢复。