kafka问题总结
这篇文章主要记录自己遇到和在网上看到的一些关于kafka的相关问题。
问题1:客户端和服务端版本不一致造成的消息发送延迟高现象
kafka客户端支持多语言api,这里只关注Java客户端,如下两种方式:
<dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka_2.11</artifactId> <version>0.10.2.0</version> </dependency>
这样会引入Java和scala两种依赖,如果只引入Java可以采用下面这种方式:
<dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>0.10.2.0</version> </dependency>
回到问题:分区Leader在进行分区数据写入的时候,为保证数据的完整性,会对分区进行加锁,同时在锁块中会有一个压缩的操作,而客户端和服务端消息版本协议不一致的话,就会造成服务端需要将客户端发送的数据解压、重新计算点位,然后再压缩的一个过程,这个过程是比较耗费性能的,就会造成其他对该分区写入的线程一直等待,从而产生较高延迟。
具体分析可参考:https://www.codingw.net/Article?id=778
问题2:broker配置副本数错误(offsets.topic.replication.factor)导致kafka消费组无法消费
现象:消费组无法消费消息,通过命令查看消费组状态,显示The coordinator is not available,协调器不可用。
原因:消费组在进行消息拉取之前,需要根据消费组成员情况、主题的分区个数进行队列负载,这个过程也称之为重平衡。
Kafka为了管理各个消费组的重平衡、位点提交、持久化等与消费组息息相关的功能,kafka服务端会为每一个消费组在服务端分配一个协调器。
为了保证Kafka协调器的高可用与负载均衡,当一个消费组开始启动消费时,会从服务端进行一次消费组协调器选举,其选举算法:
-
-
- 根据消费组的名称,取hashcode。
- 查询系统主题__consumer_offsets主题的分区个数。
- 使用消费组hashcode与_consumer_offsets主题的分区个数取模得到mod。
- 选择__consumer_offsets中分区编号为mod分区Leader所在节点的broker成为该消费组的组协调器。
-
从组协调器的选举机制来看,除非__consumer_offsets这个主题在服务端并没有创建成功,查看确实不存在这个主题。
该主题是在第一次消费的时候,会自动创建,那为什么创建不成功呢?
于是仔细看了一下broker中关于__consumer_offsets这个主题相关的配置,如下offsets.topic.replication.factor=3,但发现测试环境这个新集群中总机器数也只有2台,导致无法创建足够的副本,从而主题创建失败。
因为Kafka为了保证数据的安全性,规定同一个分区的副本不能分布在同一台机器上,所以在实践中,offsets.topic.replication.factor必须小于等于集群节点个数。