Kafka消费组无法消费问题排查实战
说来惭愧,将近5个月没有在公众号发表自己的原创文章,是什么原因耽搁了,我想有些粉丝朋友应该知道一二。并不是我这段时间没有坚持学习,而是极客时间《中间件核心技术与实战》这个专栏将我的业余时间全部占据,实在无法抽出身来进行自我学习。
朋友,越努力越幸运,唯有坚持不懈,我不在的这段时间,你们是否依然坚持在学习呢?
持续学习,努力提升职场竞争力,更好的服务公司是我们必须要重视与坚持的,并且在我们中通,领导为我们的学习也操尽了心,为我们制定了个人成长IDP,我第三季度的重心将放在努力提升Kafka相关技能,有兴趣的朋友可以加我微信(dingwpmz),与我一起学习成长。
一个测试童鞋在测试我们消息运维平台多机房集群安装时,发现在测试环境通过我们平台自动安装的Kafka集群可以进行消息发送,但无法消费消息。
遇到无法消费,从运维的角度我觉得我们可以先使用运维命令查看一下消费组的状态,我们通常使用如下命令查看消费组的状态:
./kafka-consumer-groups.sh --bootstrap-server 127.0.0.1:9092 --group dw_test_kafka_consumer_000 --describe
命令的输出结构让我比较吃惊,竟然报错了:
错误描述信息如下:
Executing consumer group command failed due to org.apache.kafka.common.errors.CoordinatorNotAvailableException: The coordinator is not available
关键日志:The coordinator is not available,表示协调器不可用!
那什么是消费组的协调器呢?消费组的协调器对职责是什么呢?
原来在Kafka中,消费组在进行消息拉取之前,需要根据消费组成员情况、主题的分区个数进行队列负载,这个过程也称之为重平衡。Kafka为了管理各个消费组的重平衡、位点提交、持久化等与消费组息息相关的功能,kafka服务端会为每一个消费组在服务端分配一个协调器。
为了保证Kafka协调器的高可用与负载均衡,当一个消费组开始启动消费时,会从服务端进行一次消费组协调器选举,其选举算法:
- 根据消费组的名称,取hashcode。
- 查询系统主题__consumer_offsets主题的分区个数。
- 使用消费组hashcode与_consumer_offsets主题的分区个数驱魔,得到mod。
- 选择__consumer_offsets中分区编号为mod分区Leader所在节点的broker成为该消费组的组协调器。
在了解了组协调器的选举流程后,那为什么消费组无法找到组协调器吗?
从组协调器的选举机制来看,除非__consumer_offsets这个主题在服务端并没有创建成功,组协调器才无法完成选举?
但 __consumer_offsets这个主题是一个系统主题,怎么会不存在呢?尽管让人怀疑,但我们还是不得不去看看服务端是否创建成功了该主题,进入到Kafka数据存储目录(该目录由broker的配置文件中 log.dirs 参数设置),一看,该主题竟然真的没有创建。
那我们不禁要问,那 __consumer_offsets这个主题是什么时候创建呢?
原来该主题是在第一次消费的时候,会自动创建,那为什么创建不成功呢?
于是我仔细看了一下broker中关于__consumer_offsets这个主题相关的配置,如下offsets.topic.replication.factor=3,但我发现测试环境这个新集群中总机器数也只有2台,导致无法创建足够的副本,从而主题创建失败。
因为Kafka为了保证数据的安全性,规定同一个分区的副本不能分布在同一台机器上,所以在实践中,offsets.topic.replication.factor必须小于等于集群节点个数。
故最终我将offsets.topic.replication.factor调整为2,并且重新启动消费组,果然就能正常消费,查看服务端日志,也看到了__consumer_offsets主题成功创建,其日志如下:
至此,问题排查,并得到最终解决。
其实这个问题比较简单,但需要我们提前具备kafka消费组的工作机制,只要了解了其运行机制,就能很快就能解决该问题,可见,知识储备的重要性。
文章转载自公众号:中间件兴趣圈