在Ubuntu上配置Kafka时,可能会遇到一些常见问题。以下是一些常见问题的解决方案:
消息堆积
- 现象:生产者狂发消息,消费者处理速度慢,导致消息积压,监控告警狂响。
- 原因:消费者代码性能差(如同步阻塞、未批量处理)。分区数不足,无法并行消费。消费者组内成员分配不均。
- 解决方案:
- 优化消费者代码:改用异步非阻塞处理(如使用线程池)。批量拉取消息(max.poll.records调大)。
- 增加分区数:
./kafka-topics.sh --alter --topic 订单日志 --partitions 6 --bootstrap-server localhost:9092
。 - 调整分配策略:使用RoundRobinAssignor替代默认的RangeAssignor,均衡负载。
数据丢失
- 现象:生产者发送成功,但消费者读不到消息。
- 原因:生产者未开启ACK确认(acks=0或1)。Leader副本宕机,且未同步到Follower。
- 解决方案:
- 生产者配置:
acks=all
# 确保所有ISR副本确认后才返回成功。retries=3
# 自动重试。 - Broker配置:
min.insync.replicas=2
# 至少2个副本确认才允许写入。
- 生产者配置:
消费者重复消费
- 现象:消费者重启或崩溃后,重复处理已读消息。
- 原因:消费者提交Offset失败(如崩溃前未提交)。自动提交Offset间隔太长(auto.commit.interval.ms默认5秒)。
- 解决方案:
- 手动提交Offset:
consumer.commitSync();
// 处理完消息后同步提交。 - 缩短自动提交间隔:
auto.commit.interval.ms=1000
// 1秒提交一次。
- 手动提交Offset:
Leader切换导致短暂不可用
- 现象:Broker宕机后,分区Leader切换期间,生产者发送消息超时。
- 解决方案:
- 增加重试机制:
retries=5
,retry.backoff.ms=1000
// 在尝试重试对给定主题分区的失败请求之前等待的时间。 - 客户端缓存消息:生产者启用本地缓存(如Kafka的
buffer.memory
),避免消息丢失。
- 增加重试机制:
磁盘写满,Broker罢工
- 现象:Broker日志磁盘占用100%,无法写入新消息。
- 解决方案:
- 紧急清理过期日志:
./kafka-delete-records.sh --bootstrap-server localhost:9092 --offset-json-file cleanup.json
。 - 预防配置:
log.retention.hours=72
# 缩短保留时间。log.retention.bytes=1073741824
# 每个分区最多保留1GB。
- 紧急清理过期日志:
ZooKeeper连接闪断,集群抖动
- 现象:频繁报错“ZooKeeper session expired”,Controller频繁切换。
- 解决方案:
- 优化ZooKeeper配置:
zookeeper.session.timeout.ms=18000
# 增加会话超时时间。 - 监控ZooKeeper配置:避免ZooKeeper集群压力过大(如分离Kafka和ZooKeeper的物理资源)。
- 优化ZooKeeper配置:
消费者组重平衡太频繁
- 现象:消费者组频繁重新分配分区,导致消费暂停。
- 原因:消费者心跳超时(处理消息时间过长,未及时发送心跳)。网络波动导致Group Coordinator认为消费者下线。
- 解决方案:
- 紧急清理过期日志:
session.timeout.ms=30000
# 心跳超时时间调大。max.poll.interval.ms=300000
# 拉取消息间隔上限调大。 - 优化消息处理逻辑:避免单条消息处理耗时过长。
- 紧急清理过期日志:
跨机房同步延迟高
- 现象:异地多机房部署时,副本同步延迟高,ISR列表不稳定。
- 解决方案:
- 优先同机房同步:
broker.rack=us-east-1a
# 标记Broker所在机房。 - 调整副本拉取参数:
replica.socket.timeout.ms=120000
# 增加副本同步超时时间。
- 优先同机房同步:
希望这些信息能帮助你在配置Kafka时避免一些常见问题。如果问题依然存在,建议查看Kafka的官方文档或寻求社区的帮助。