同组ID的两个Kafka控制台消费者未实现负载分担问题排查
首先纠正一个认知偏差:Kafka同组消费者的消息分配是基于分区,而非按消息顺序均分。你的topic有4个分区,两个同组消费者的正确分配逻辑是每个消费者分到2个分区,每个分区内的所有消息都会被对应的消费者接收,而不是把消息按顺序拆成前4条和后4条分给两个消费者。
回到你的问题,所有消息都到一个消费者,可能是以下原因,对应排查和解决方法:
1. 消费者组未完成分区重平衡
先确认两个消费者是否都成功加入了目标组,执行以下命令查看组的详细状态:
./kafka-consumer-groups.sh --describe --group console-consumer-37108 --bootstrap-server localhost:9092
如果输出里只显示一个消费者的信息,说明第二个消费者未成功加入组,检查启动命令是否正确,或者broker连接是否正常。
2. 旧消费位移干扰
之前你用console-consumer-37108这个组消费过,可能该组的位移已经处于topic的最新位置,新启动的消费者会直接从最新位移开始消费,导致看起来只有一个消费者在接收新消息。解决方法是重置该组的位移到最早位置:
./kafka-consumer-groups.sh --reset-offsets --to-earliest --topic my-topic --group console-consumer-37108 --execute --bootstrap-server localhost:9092
重置完成后,重新启动两个消费者,再发送消息测试。
3. 分区分配策略问题
Kafka默认的分区分配策略(如CooperativeStickyAssignor)可能在某些场景下不会立即触发均匀分配,你可以强制指定轮询分配策略,确保分区均匀分给消费者:
- Terminal 1启动命令:
./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic my-topic --group console-consumer-37108 --partition-assignment-strategy org.apache.kafka.clients.consumer.RoundRobinAssignor
- Terminal 2启动命令:
./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic my-topic --group console-consumer-37108 --partition-assignment-strategy org.apache.kafka.clients.consumer.RoundRobinAssignor
4. 生产者消息分配不均
如果你的生产者发送消息时指定了相同的key,所有消息会被路由到同一个分区,自然只会被一个消费者接收。可以检查每个分区的消息数,确认是否均匀:
./kafka-run-class.sh kafka.tools.GetOffsetShell --topic my-topic --time -1 --bootstrap-server localhost:9092
输出的每个分区的offset差值就是该分区的消息数,如果某个分区消息数远高于其他,说明生产者的key策略导致了分区分布不均,调整生产者的key或者使用无key的方式发送消息即可。
内容的提问来源于stack exchange,提问作者Thiagarajan Ramanathan

