Topic管理:从创建到运维的实战心法
Topic是Kafka里最核心的数据载体。说白了,你集群里跑的所有消息,最终都落在某个Topic的分区里。我刚开始接触Kafka时,觉得Topic不就是建个名字嘛,后来线上踩了几次坑才明白——Topic的创建、分区分配、副本机制,每一步都藏着门道。
这一章,我把这些年管理Topic的经验掰开揉碎讲给你听。咱们从最基础的创建删除开始,再到分区副本的底层逻辑,最后聊聊手动重分配这种高阶操作。
Topic的创建与删除
创建Topic有两种方式:自动创建和手动创建。生产环境我强烈建议你关掉自动创建。
手动创建的命令很简单:
# 创建一个名为"order-events"的Topic,6个分区,3个副本
bin/kafka-topics.sh --create \
--bootstrap-server localhost:9092 \
--topic order-events \
--partitions 6 \
--replication-factor 3 \
--config retention.ms=604800000 \
--config max.message.bytes=1048576
这里有几个参数我重点说一下:
- partitions:分区数决定了并行处理能力。我一般建议分区数是消费者组内消费者数的整数倍,最好是2-3倍。
- replication-factor:副本数。3副本是生产环境的标配,既能保证高可用,又不会浪费太多存储。
- --config:可以覆盖Topic级别的配置。比如retention.ms控制数据保留时间,max.message.bytes控制单条消息大小。
删除Topic要小心:
# 删除Topic
bin/kafka-topics.sh --delete \
--bootstrap-server localhost:9092 \
--topic order-events
分区与副本机制
分区是Kafka实现水平扩展的基石。每个分区都是一个有序的日志文件,消息按顺序追加。副本则是保证数据不丢的关键。
咱们来看一张分区副本的结构图:
这张图展示了一个3分区、3副本的Topic。每个分区都有一个Leader副本和两个Follower副本。Leader负责处理客户端的读写请求,Follower则从Leader同步数据。
- Leader和Follower分布在不同的Broker上,保证单点故障时数据不丢
- ISR(In-Sync Replicas)是跟Leader保持同步的副本集合
- 只有ISR里的副本才有资格被选举为新的Leader
分区分配策略
创建Topic时,Kafka需要决定每个分区的Leader和Follower放在哪些Broker上。这就是分区分配策略干的事。
Kafka默认的策略是轮询分配。举个例子,3个Broker、6个分区、3副本:
| 分区 | Leader | Follower 1 | Follower 2 |
|---|---|---|---|
| Partition 0 | Broker 1 | Broker 2 | Broker 3 |
| Partition 1 | Broker 2 | Broker 3 | Broker 1 |
| Partition 2 | Broker 3 | Broker 1 | Broker 2 |
| Partition 3 | Broker 1 | Broker 2 | Broker 3 |
| Partition 4 | Broker 2 | Broker 3 | Broker 1 |
| Partition 5 | Broker 3 | Broker 1 | Broker 2 |
你看,每个Broker上的Leader数量是均匀的(2个),Follower数量也是均匀的(4个)。这种策略的好处是负载均衡,坏处是没考虑机架感知。
手动分区重分配
集群跑久了,难免会遇到负载不均的情况。比如新加了Broker,或者某个Broker磁盘快满了。这时候就需要手动做分区重分配。
我遇到过最典型的情况:集群从3台扩容到6台,结果新Broker上空空如也,老Broker上压力山大。手动重分配就是用来解决这个问题的。
操作步骤分三步:
- 生成分配计划:用kafka-reassign-partitions.sh生成一个JSON文件,描述每个分区的新位置。
- 执行分配:提交计划,Kafka会逐步把分区迁移到新位置。
- 验证结果:确认所有分区都迁移完成。
来看一个实际例子。假设我要把Topic "order-events" 的Partition 0从Broker 1迁移到Broker 4:
# 1. 生成分配计划
cat > reassign-plan.json << EOF
{
"version": 1,
"partitions": [
{
"topic": "order-events",
"partition": 0,
"replicas": [4, 2, 3]
}
]
}
EOF
# 2. 执行分配
bin/kafka-reassign-partitions.sh \
--bootstrap-server localhost:9092 \
--reassignment-json-file reassign-plan.json \
--execute
# 3. 验证进度
bin/kafka-reassign-partitions.sh \
--bootstrap-server localhost:9092 \
--reassignment-json-file reassign-plan.json \
--verify
还有一个常见场景:Leader分布不均。有时候虽然副本分布均匀,但Leader都集中在某几个Broker上。这时候可以用优先副本选举来重新平衡Leader:
# 对所有Topic执行优先副本选举
bin/kafka-leader-election.sh \
--bootstrap-server localhost:9092 \
--election-type preferred \
--all-topic-partitions
这个操作不会移动数据,只是把Leader切换回优先副本(即副本列表中的第一个)。速度很快,对集群影响小。
- 创建Topic时,分区数要预留扩展空间。我一般按未来6个月的数据量估算,再乘以1.5的系数。
- 副本数3是黄金标准,别为了省磁盘设成2,也别浪费资源设成4以上。
- 手动重分配是运维利器,但一定要限速、限并发、选低峰期。
- 定期检查Leader分布,用优先副本选举保持负载均衡。
嗯,Topic管理这块内容不少,但核心就是这几板斧。你把这些搞透了,日常运维基本不会出大问题。