Topic 管理
定义与作用
Topic 管理是 Kafka 运维最频繁的操作。包括 Topic 的创建、配置修改、分区扩容、查看详情和删除。本节覆盖 kafka-topics.sh 的完整用法及生产环境最佳实践。
核心原理
Topic 管理操作全景
分区数不可减少
分区不可降的原因:
- 数据已按 Key Hash 分布到各分区,合并会破坏分区语义
- Consumer 的 Offset 与分区绑定,删除分区会导致 Offset 失效
- 分区内部有序,合并多个分区无法保证合并后有序
完整示例
示例一:Topic 完整生命周期
# 1. 创建 Topic
bin/kafka-topics.sh --create --topic orders \
--partitions 6 --replication-factor 3 \
--config retention.ms=604800000 \
--config min.insync.replicas=2 \
--config max.message.bytes=1048576 \
--bootstrap-server localhost:9092
# 2. 查看详情
bin/kafka-topics.sh --describe --topic orders --bootstrap-server localhost:9092
# Topic: orders PartitionCount: 6 ReplicationFactor: 3 Configs: ...
# Partition: 0 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3
# Partition: 1 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1
# ...
# 3. 分区扩容(只能增加)
bin/kafka-topics.sh --alter --topic orders \
--partitions 12 --bootstrap-server localhost:9092
# 4. 修改配置
bin/kafka-configs.sh --bootstrap-server localhost:9092 \
--entity-type topics --entity-name orders \
--alter --add-config retention.ms=259200000
# 5. 查看覆盖配置
bin/kafka-configs.sh --bootstrap-server localhost:9092 \
--entity-type topics --entity-name orders --describe
# 6. 删除 Topic(需 broker 配置 delete.topic.enable=true)
bin/kafka-topics.sh --delete --topic orders --bootstrap-server localhost:9092
操作前后对比:
| 操作 | 前 | 后 |
|---|---|---|
| 创建 | 无 | 6 分区,3 副本 |
| 扩容 | 6 分区 | 12 分区 |
| 修改配置 | retention=7天 | retention=3天 |
| 删除 | 12 分区 | 无 |
示例二:列出所有 Topic 并过滤
# 列出所有 Topic
bin/kafka-topics.sh --list --bootstrap-server localhost:9092
# orders
# payments
# logs
# __consumer_offsets
# __transaction_state
# 排除内部 Topic
bin/kafka-topics.sh --list --bootstrap-server localhost:9092 \
--exclude-internal
# orders
# payments
# logs
# 查看有问题的 Topic(无 Leader 的分区)
bin/kafka-topics.sh --describe --under-replicated-partitions \
--bootstrap-server localhost:9092
# Partition: 5 Leader: -1 Replicas: 3,1,2 Isr: 1,2
# → Partition 5 无 Leader,需排查
易错场景
易错 1:分区扩容后数据不均匀
场景:分区从 3 扩到 6,但新分区没数据,Producer 的 Key Hash 映射到了新分区。
后果:消费端如果依赖分区内有序性——扩容后同一个 Key 可能换分区,有序性被破坏。且新分区的 Consumer 最初消费不到数据。
事实:分区扩容后已有数据不会自动重分布。只有新写入的数据才会到新分区。扩容不保证顺序消费。
易错 2:未设 min.insync.replicas 即上生产
场景:Topic 创建时使用默认 min.insync.replicas=1。
后果:acks=all 等价于 acks=1,无 Follower 确认。Leader 故障时可能丢数据。
最佳实践:生产 Topic 创建模板:
bin/kafka-topics.sh --create --topic <name> \
--partitions <N> \
--replication-factor 3 \
--config min.insync.replicas=2 \
--config retention.ms=<N> \
--bootstrap-server localhost:9092
面试高频考点
Q:为什么 Kafka 分区数只能增加不能减少?如果业务数据量下降怎么办?
A:
- 数据完整性:删除分区意味着删除其所有数据,与分区内不可变追加语义冲突
- Consumer Offset:删分区会导致 Offset 失效,Consumer 无法继续消费
- Key 路由:Partitioner 基于
hash(key) % partitionCount,减分区会破坏所有 Key 的路由一致性
实际做法:
- 短期:保留分区(无数据不影响性能,只是元数据多几项)
- 长期:创建新 Topic,迁移消费组到新 Topic,废弃旧 Topic
- 使用
kafka-reassign-partitions.sh将分区数据迁移到其他 Topic(重分配不算"减少"分区数)