SRE 每日主题:Kafka 集群部署与运维指南
日期:2026-03-05 | 主题索引:5/12 | 适用环境:Linux (RHEL/CentOS/Ubuntu), JDK 17+, Kafka 3.7+
🎯 核心目标
构建高可用、低延迟、可观测的 Kafka 生产集群,满足金融级 SLA(99.99% uptime, <50ms p99 produce latency)。
🧱 基础架构要求
| 维度 | 推荐配置 | 说明 |
|---|---|---|
| 节点数 | ≥3 ZooKeeper + ≥3 Kafka brokers | ZooKeeper 必须奇数;Kafka broker ≥3 实现 ISR 容错 |
| CPU | 16+ vCPUs per broker | 吞吐密集型(网络/磁盘 I/O 为主,但 GC 压力大) |
| 内存 | 32–64 GB RAM | JVM heap ≤ 8 GB(避免 GC 停顿),剩余为 page cache |
| 磁盘 | RAID-10 SSD (≥2 TB) or NVMe | log.dirs 必须挂载独立高性能卷;禁用 ext4 barrier=1,启用 noatime,nobarrier |
| 网络 | 10 GbE bonded, low-latency switch | 禁用 TCP delayed ACK (net.ipv4.tcp_delack_min=0) |
✅ 生产检查清单:
- 所有节点时间同步(chrony + makestep 1 -1)
- /etc/hosts 全网解析一致(禁用 DNS 查找)
- vm.swappiness=1,vm.dirty_ratio=80,vm.dirty_background_ratio=5
- ulimit -n 1000000(broker 进程)
⚙️ 核心配置模板
config/zookeeper.properties
# --- Cluster Identity ---
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888
# --- Performance & Safety ---
dataDir=/var/lib/zookeeper/data
clientPort=2181
initLimit=10
syncLimit=5
autopurge.snapRetainCount=5
autopurge.purgeInterval=24
# --- Security (enable in prod) ---
secureClientPort=2281
quorum.auth.enableSasl=true
quorum.auth.learnerRequireSasl=true
config/server.properties(Broker 通用模板)
# --- Identity ---
broker.id=1
node.id=1
process.roles=broker,controller
# --- Listeners & Networking ---
listeners=PLAINTEXT://:9092,SSL://:9093,SASL_SSL://:9094
advertised.listeners=PLAINTEXT://kafka1.example.com:9092,SSL://kafka1.example.com:9093,SASL_SSL://kafka1.example.com:9094
listener.security.protocol.map=PLAINTEXT:PLAINTEXT,SSL:SSL,SASL_SSL:SASL_SSL
inter.broker.listener.name=SASL_SSL
# --- Log & Storage ---
log.dirs=/data/kafka-logs
num.partitions=12
default.replication.factor=3
min.insync.replicas=2
unclean.leader.election.enable=false
# --- Performance Tuning ---
num.network.threads=8
num.io.threads=16
socket.send.buffer.bytes=1024000
socket.receive.buffer.bytes=1024000
socket.request.max.bytes=104857600
log.flush.interval.messages=10000
log.retention.hours=168
log.segment.bytes=1073741824
log.roll.hours=168
# --- JVM (set in bin/kafka-server-start.sh) ---
KAFKA_HEAP_OPTS="-Xms4g -Xmx4g -XX:+UseG1GC -XX:MaxGCPauseMillis=20"
🔑 关键参数说明:
min.insync.replicas=2: 写入需至少 2 个副本落盘才返回 ACK → 保证 RPO≈0(单点故障不丢数据)unclean.leader.election.enable=false: 禁止非 ISR 副本成为 leader → 防止数据丢失(牺牲可用性保一致性)log.segment.bytes=1G: 大 segment 减少文件句柄压力,但需配合log.roll.hours防止单文件过大num.io.threads=16: ≥ CPU 核心数 × 2(SSD 随机 I/O 并发高)
📊 监控与可观测性
✅ 必备监控指标(Prometheus + JMX Exporter)
| Group | Metric | Alert Threshold | Purpose |
|---|---|---|---|
kafka_server_replicamanager |
UnderReplicatedPartitions |
> 0 for 5m | ISR 缩减,副本同步滞后 |
kafka_controller_kafkacontroller |
ActiveControllerCount |
≠ 1 | Controller 故障或脑裂 |
kafka_server_brokertopicmetrics |
MessagesInPerSec |
sudden drop >50% | 生产者中断 |
kafka_network_requestmetrics |
RequestHandlerAvgIdlePercent |
< 20% | 请求线程池过载 |
kafka_log_log |
LogFlushRateAndTimeMs |
p99 > 500ms | 磁盘写入瓶颈 |
🛠️ 日常运维命令速查
# 查看所有 topic 及分区状态(含 under-replicated)
kafka-topics.sh --bootstrap-server kafka1:9092 --list --describe
# 查看 consumer group 滞后(Lag)
kafka-consumer-groups.sh --bootstrap-server kafka1:9092 \
--group payment-service --describe
# 强制重平衡(慎用!仅当 group 卡死)
kafka-consumer-groups.sh --bootstrap-server kafka1:9092 \
--group legacy-app --reset-offsets --to-earliest --execute
# 查看 controller 选举历史(ZooKeeper)
kafka-run-class.sh kafka.admin.ZookeeperClusterTool \
--zookeeper-connect zoo1:2181,zoo2:2181,zoo3:2181 \
--topic __cluster_metadata --describe
# 检查磁盘使用率(每个 broker)
df -h /data/kafka-logs
🚨 故障排查手册
| 现象 | 根因定位 | 解决方案 | |
|---|---|---|---|
| Producer TimeoutException | NetworkException / NotEnoughReplicasException |
① kafka-topics.sh --describe 检查 ISR;② `netstat -tnp \ |
grep :909*检查端口连通性;③ 检查request.timeout.ms和delivery.timeout.ms` 是否过小 |
| Consumer Lag 持续增长 | fetch.min.bytes=1 + fetch.wait.max.ms=500 导致轮询空响应 |
调大 fetch.min.bytes=1024,降低 fetch.wait.max.ms=100;检查 consumer GC pause |
|
| Controller 切换频繁 | ZooKeeper session timeout(默认 6s)被触发 | 调大 zookeeper.session.timeout.ms=18000,并确保 zookeeper.sync.time.ms=2000 |
|
| 磁盘空间不足告警 | log.retention.bytes 未设或过大,且无自动清理 |
① 立即执行 kafka-delete-records.sh 清理旧 topic;② 设置 log.retention.bytes=107374182400(100GB)强制上限 |
✅ 最佳实践与常见陷阱
✅ 强烈推荐
- Rack Awareness: 在
server.properties中设置broker.rack=rack1,并在创建 topic 时指定--replica-assignment或使用--broker-rack参数,确保副本跨机架分布。 - ACL 强制启用: 使用
kafka-acls.sh配置最小权限原则(e.g.,User:CN=produceronlyWRITEontopic.payment)。 - Quotas: 对高流量 client ID 设置
kafka-configs.sh --alter --entity-type clients --entity-name "payment-app" --add-config "producer_byte_rate=10485760,consumer_byte_rate=20971520"。 - Log Compaction: 对 KV 类 topic(如用户画像)启用
cleanup.policy=compact,避免无限增长。
⚠️ 绝对禁止
- ❌ 在生产环境使用
auto.create.topics.enable=true(易导致 topic 名称污染、分区数错误) - ❌ 将
log.dirs挂载到根分区/或/home(IO 争抢 + 空间耗尽风险) - ❌ 使用
delete.topic.enable=false(无法清理废弃 topic,磁盘终将满) - ❌ 关闭
compression.type=producer(客户端压缩可降低 70% 网络带宽)
📚 延伸阅读
- Apache Kafka Official Documentation
- LinkedIn Engineering: Kafka at Scale
- Confluent Production Best Practices
📝 SRE 提示:每日凌晨 2:00 自动运行
kafka-log-dirs.sh --bootstrap-server ... --describe并比对各 broker log dir 使用率差异(>15% 触发告警),预防“热点 broker”。
Generated by OpenClaw SRE Daily Topic Generator — 2026-03-05