Kafka 日常操作与配置指南
本文档整理了 Kafka 常用的运维操作命令与核心配置参数。配置怎么设、设完之后日常怎么操作和排查,是同一条链路的两半——只看配置不理解操作,只会写不会调;只看操作不理解配置,改坏了自己的集群还不知道。
版本说明
本文写于 2022-03。
本文所涉命令基于 Kafka 传统 Zookeeper 模式;Kafka 3.3+ 引入 KRaft 模式(4.0 起默认移除 Zookeeper 依赖),若集群已切换 KRaft,部分涉及 Zookeeper 的运维命令(如查看 Broker 元数据的路径)需改用 kafka-metadata-quorum.sh 等新工具,其余日常生产消费类命令不受影响。配置参数方面,KRaft 模式下 zookeeper.connect 相关参数不再需要,替换为 process.roles/controller.quorum.voters,但 Broker 侧存储、网络类配置项含义未变。
# 1. Topic 管理操作
# 1.1 创建 Topic
kafka-topics.sh --create \
--zookeeper localhost:2181 \
--replication-factor 3 \
--partitions 10 \
--topic test
2
3
4
5
# 1.2 Topic 查看操作
查看所有 topic 列表:
kafka-topics.sh --list --zookeeper localhost:2181
查看指定 topic 详细信息:
kafka-topics.sh --zookeeper localhost:2181 --describe --topic test
# 1.3 Topic 修改操作
增加 topic 分区数:
kafka-topics.sh --zookeeper localhost:2181 --alter --topic test --partitions 10
设置数据保留大小(例如限制为 60G):
kafka-configs.sh --zookeeper localhost:2181 \
--alter --entity-type topics \
--entity-name test \
--add-config retention.bytes=60737418240
2
3
4
设置数据保留时间(例如保留3天):
kafka-configs.sh --zookeeper localhost:2181 \
--alter --entity-type topics \
--entity-name test \
--add-config retention.ms=259200000
2
3
4
# 1.4 删除 Topic
kafka-topics.sh --zookeeper localhost:2181 --delete --topic test
坑:删除操作需要在 server.properties 中配置 delete.topic.enable=true,否则只会将 topic 标记为待删除状态,不会实际释放磁盘空间。
# 2. 消息生产和消费
# 2.1 消费 Topic 数据
kafka-console-consumer.sh --bootstrap-server localhost:9092 \
--topic test \
--from-beginning
2
3
# 2.2 生产数据到 Topic
kafka-console-producer.sh --broker-list localhost:9092 --topic test
# 3. 消费组管理
# 3.1 查看消费组列表
kafka-consumer-groups.sh --bootstrap-server localhost:9092 --list
# 3.2 查看消费组详情
kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
--describe --group mygroup
2
# 3.3 删除消费组
kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
--delete --group test
2
# 4. 核心配置参数及其原理
# 4.1 基础配置
# Broker 唯一标识符
broker.id=5
# 监听端口
port=9001
# 对外发布的监听地址
advertised.listeners=PLAINTEXT://test-node001:9001
# 主题相关配置
auto.create.topics.enable=false
num.partitions=10
default.replication.factor=3
# 数据存储目录
log.dirs=/data/kafka9001
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 4.2 网络配置
# 网络线程数
num.network.threads=3
# IO线程数
num.io.threads=8
# 消息大小限制(约 1GB)
message.max.bytes=1000012000
# Socket 配置
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
2
3
4
5
6
7
8
9
10
11
12
13
性能调优:num.network.threads 负责处理网络 I/O 并将请求放入请求队列,num.io.threads 从队列中取出请求并进行磁盘 I/O。CPU 核心数多、流量大时可适当增大这两个值;反之则可降低以节省资源。
# 4.3 数据保留配置
# 数据保留时间(小时)
log.retention.hours=48
# 单个日志段大小(1GB)
log.segment.bytes=1073741824
# 检查间隔
log.retention.check.interval.ms=300000
2
3
4
5
6
7
8
注意:清理不是即时的——由 log.retention.check.interval.ms(默认 5 分钟)周期性检查触发,而且只能删除已经滚动关闭的非活跃 segment,当前正在写入的 segment 不参与清理。所以磁盘水位会有一段滞后,规划空间时要留出余量。
# 4.4 复制和一致性配置
# 最小同步副本数
min.insync.replicas=1
# 副本数
default.replication.factor=3
# 副本拉取线程数
num.replica.fetchers=2
# 禁用不干净的领导者选举
unclean.leader.election.enable=false
# 禁用自动领导者平衡
auto.leader.rebalance.enable=false
2
3
4
5
6
7
8
9
10
11
12
13
14
# 4.5 ZooKeeper 配置
# ZooKeeper 连接字符串
zookeeper.connect=192.0.2.11:2181,192.0.2.12:2181,192.0.2.13:2181,192.0.2.14:2181,192.0.2.15:2181
# ZooKeeper 连接超时时间
zookeeper.connection.timeout.ms=6000
2
3
4
5
# 4.6 其他重要配置
# 消费者组初始重平衡延迟
group.initial.rebalance.delay.ms=0
# 启用受控关闭
controlled.shutdown.enable=true
# 请求超时时间
request.timeout.ms=60000
2
3
4
5
6
7
8
监控建议:定期检查 log.retention.hours 确保符合数据保留需求,监控 log.dirs 的磁盘使用情况水位。
# 5. 配置为什么这么设
# 5.1 num.partitions 与消费者并行度的关系
num.partitions 决定了每个 topic 默认的分区数量。分区是 Kafka 并行度的基本单位——一个分区同一个时刻只能被一个消费者线程消费,因此消费者并行度上限等于分区数。如果消费者组有 10 个消费者,但 topic 只有 3 个分区,那么最多只有 3 个消费者真正在干活。
经验公式:消费者线程总数 ≈ 分区数,或者在 IO 密集场景下分区数略多于线程数。
分区过多的代价:
- 每个分区在 broker 上都是一组独立的文件(索引 + 数据),分区数上万时会消耗大量文件句柄和页缓存
- controller 需要为每个宕机的 broker 重新为受影响的所有分区选主,分区越多故障恢复越慢
- producer 端每个分区各自攒批,分区太多会使每批数据变小、压缩率和网络效率下降
- 端到端延迟随之上升
# 5.2 log.retention.hours 与 log.retention.bytes 谁先触发
Kafka 的数据保留策略是两者取先触发:
log.retention.hours:按时间保留,超过这个时间的日志段会被删除log.retention.bytes:按总大小保留,每个分区超出这个大小后最早的日志段会被删除
这意味着即使用户设了 7 天保留,如果某个分区的日志文件总大小超过了 log.retention.bytes,就会触发清理——但不是"立即"删除,而是等下一个检查周期(默认 5 分钟)且只清理已关闭的 segment。规划磁盘空间时必须同时考虑两个参数,任何一个达到阈值都会触发清理。
# 5.3 min.insync.replicas 必须与 producer acks=all 配对使用
min.insync.replicas 指定了每个写入请求最少需要确认同步成功的副本数。如果 producer 设置 acks=all(要求所有同步副本确认),但 broker 侧 min.insync.replicas=1,则实际保证只有 1 个副本同步成功即可——只设其一等于没有保证。
正确配对:
- Broker:
min.insync.replicas=2(假设副本数=3) - Producer:
acks=all
只有这样,才能保证写入的数据至少在 2 个副本上持久化,即使一个节点宕机也不丢数据。
坑:如果 min.insync.replicas 设置等于副本数(即没有冗余),挂掉一个节点就会导致整个 topic 无法写入——因为无法满足最小同步副本数要求。
# 5.4 unclean.leader.election.enable 的风险
默认 unclean.leader.election.enable=false,即不允许非同步副本成为 leader。这意味着只有 ISR(In-Sync Replicas)列表中的副本才能被选为 leader,可以保证不丢失数据。
如果设为 true,允许不在 ISR 列表中的副本成为 leader——这些副本可能落后主库很多数据,成为 leader 后这些未同步的数据就会永久丢失。这在某些"宁可丢数据也要服务可用"的场景下可以打开,但大多数生产环境应该保持默认关闭。
# 6. 验证:配置改完怎么确认真的生效
# 6.1 查看 topic 级别的动态配置
配置改完,用 kafka-configs.sh 确认生效:
kafka-configs.sh --zookeeper localhost:2181 \
--describe --entity-type topics --entity-name test
2
会列出该 topic 的所有覆盖配置项及当前值。
# 6.2 确认副本分布均匀
topic 建完或分区调整后,检查副本分布:
kafka-topics.sh --zookeeper localhost:2181 --describe --topic test
关注 Isr 列——这是当前与 leader 保持同步的副本列表。如果某个分区的 ISR 只包含一个 broker,说明其他副本落后或失联,需要排查网络或负载问题。
# 6.3 查看消费组滞后
kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
--describe --group mygroup
2
关键看 LAG 列——表示消费进度落后生产者的消息数。如果 LAG 持续增长,说明消费者处理速度跟不上生产速度,可能需要增加消费者数量或优化消费逻辑。
# 6.4 实时监控消费组状态
watch -d kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
--describe --group mygroup
2
# 7. 坑与边界
Kafka 不支持减少分区:
kafka-topics.sh --alter --topic xxx --partitions N传一个比当前值小的 N 会直接报InvalidPartitionsException。如果要减少分区,只能重建 topic 并重新灌入数据。增加分区会破坏 key 到分区的映射:Kafka 默认分区器按
hash(key) % 分区数计算落点,分母改变后同一 key 会被路由到不同分区,导致同 key 消息的顺序保证断裂。业务侧必须能接受这种顺序变化才可增加分区。min.insync.replicas设得等于副本数时,挂一个节点就整个不可写:因为无法满足最小同步副本数要求,生产者会报NotEnoughReplicasException。生产环境建议设副本数 - 1。删 topic 需要
delete.topic.enable=true:否则只是标记删除,磁盘空间不会释放。
# 8. 集群管理
# 8.1 查看集群节点
通过 ZooKeeper 客户端查看 broker 节点:
# 1. 连接到 ZooKeeper
zkCli.sh -server localhost:2181
# 2. 查看 broker 列表
ls /brokers/ids
2
3
4
5
# 8.2 调整副本分配
创建副本重分配配置文件 (replication.json):
{
"version": 1,
"partitions": [
{
"topic": "test_topic",
"partition": 0,
"replicas": [1, 2, 3]
}
]
}
2
3
4
5
6
7
8
9
10
执行副本重分配:
kafka-reassign-partitions.sh --zookeeper localhost:2181 \
--reassignment-json-file replication.json \
--execute
2
3
# 9. 可复用要点
- 分区数决定消费者并行度上限,消费者线程数不应远大于分区数;但分区数也不是越多越好,过多会消耗文件句柄、增加故障恢复时间、降低 producer 攒批效率。
log.retention.hours与log.retention.bytes是"或"的关系,任意一个触发都会删除数据;清理有 5 分钟检查间隔且只清理已关闭的 segment。min.insync.replicas必须与 producer 的acks=all配对使用,单独设置任一个都不保证数据不丢。unclean.leader.election.enable=false是生产环境的默认安全设置,打开可能丢数据。- Kafka 不支持减少分区,要减少只能重建 topic;增加分区会破坏带 key 消息的顺序保证,业务需评估。
# Agent 可直接解析的元数据块
{
"runbook": {
"task": "kafka-operations-and-configuration",
"permalinks": ["/pages/101c03/"],
"category": "database/数据管道",
"tags": ["kafka", "topic", "consumer-group", "partition", "replication", "retention"],
"kafka_versions": ["2.x", "3.x"],
"verified_date": "2026-09"
}
}
2
3
4
5
6
7
8
9
10