前因
今天在调应用的时候,email-service服务无法收发邮件。
看到这种问题,我先去查了一下email-service的日志,看到了kafka的一个报错:
Group coordinator lookup for group email-service failed
然后我就去查资料,解决这个问题。
解决
首先,我想先去清空一下这个email-service消费组的offset,但是它仍然报出了coordinator failed这种字样的错误。那我就想了,kafka的这个coordinator(协调器)到底是什么东西,是怎么工作的。
害,先不管这个了,毕竟要先排掉错误嘛,原理放在后边说。
于是我重启了应用,再去查询email-service的日志时,发现这个错误:
Group coordinator lookup for group email-service failed: The coordinator is not available
于是我去查询kafka的配置文件,果然发现了问题。
在配置文件中(默认为config/server.properties), 将这几项参数修改成下面的样子:
offsets.topic.replication.factor=3
transaction.state.log.replication.factor=3
transaction.state.log.min.isr=2
然后重启kafka,报错消除。
解释
之前的文章抛出了一个问题,什么是协调器(coordinator)。
顾名思义,协调器(coordinator)就是负责协调工作。简单点说,就是消费者启动后,到可以正常消费前,这个阶段的初始化工作。消费者可以运行起来,全靠协调器的工作。
主要的协调器有以下两种:
- 消费者协调器
- 组协调器
kafka引入协调器有其历史过程,原来consumer信息依赖于zookeeper存储,当代理或消费者发生变化时,引发消费者平衡,此时消费者之间是互不透明的,每个消费者和zookeeper单独通信,容易造成羊群效应和脑裂问题。
为了消除此问题,kafka引入了协调器。
-
服务端引入了组协调器(GroupCoordinator),消费者端引入消费者协调器(ConsumerCoordinator)。
-
每个broker启动的时候,都会创建组协调器实例,管理部分消费组和组下每个消费者消费的偏移量。
-
每个消费者实例化时,同时实例化一个消费者协调器,负责同个消费组下各个消费者和服务端组协调器之间的通信。
由于zookeeper并不适合频繁的写入操作,从0.8.2版本开始kafka开始将consumer的位移信息写入kafka内部的topic中,具体为"__consumer_offsets"。并且默认提供了kafka_consumer_groups.sh脚本,方便用户查询consumer group和consumer信息。
我们可以查看__consumer_offsets的内容,它包括三部分内容:
<Group ID,主题名,分区号>
PS: 这个__consumer_offsets是kafka内部的topic,外界无法直接读取此topic里边的信息。如果要读取的话,需要先修改config/consumer.properties中的"exclude.internal.topics"参数,将其置为false,如下:
exclude.internal.topics=false
然后通过命令来查询信息:
# 0.11.0.0之前版本
sh kafka-console-consumer.sh --topic __consumer_offsets --zookeeper localhost:2181 --formatter "kafka.coordinator.GroupMetadataManager\$OffsetsMessageFormatter" --consumer.config config/consumer.properties
# 0.11.0.0之后版本(含)
sh kafka-console-consumer.sh --topic __consumer_offsets --bootstrap-server localhost:9092 --formatter "kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter" --consumer.config config/consumer.properties