除了对Kafka参数的调整,我们还要根据业务处理逻辑对消费者组进行提前规划,避免为了方便将业务相关的topic同时划分到同一个大消费者组,这样一旦某个消费者出现问题,将会导致整个消费者组重新Rebalace。
需求
《Bug:Zabbix对Kafka topic积压数据监控》一文我们通过监控lag来对Kafka某个分区topic的消费情况进行告警。通过告警我们发现,分区topic的消费积压情况告警非常频繁,这无疑会引起开发、运维的重点关注。经过一系列的监控、摸索、实践、总结,我们逐步发现分区topic的消费积压和以下几种情况有关:
- 消费者组频繁出现Rebalance,导致整个消费者组下的topic都无法消费;
- 消费者性能问题,无法在超时时间内完成消费;
- topic分区数和消费者数量不均衡,一个消费者需要消费多个分区topic,消费缓慢;
- topic分区数量变化;
- 等等
从以上几种情况分析,无论哪种都和消费者组Rebalance有相关性,都是在经过Rebalance后再重新消费。因此我们还得从Rebalance的角度再出发。
Rebalance再出发
其中关于消费者性能问题,这大多和客户端的参数设置不恰当相关,这是运维比较难觉察导致。但是为了更全面的了解Kafka,我们运维还是很有必要去轻了解下的。先从相关参数说起:
# 消费者每次poll()最大消费消息数量,默认500条
max.poll.records
# 两次poll()之间的最大间隔,默认值为5分钟
max.poll.interval.ms
这个参数定义了两次poll()之间的最大间隔,「默认值为5分钟」。如果业务处理消息时间过长,则会导致两次poll()的时间间隔大于超时时间,从而触发Rebalance。因此我们应该适当调整每次poll()的数量,以保证在规定时间内处理完消息,这就需要关注max.poll.records参数了。
这个参数定义了poll()方法最多可以返回多少条消息,「默认值为500」。poll()的数量如何定义,需要根据业务处理逻辑来决定,例如数据要经过多个数据源进行处理,一旦某一数据源访问超时,无疑都会降低消费效率。比较友好的解决方案是,开发可以根据不同的情况实时调整相关参数,应用侧动态感知并进行自动热加载,达到快速调整消费的效果。
除了对Kafka参数的调整,我们还要根据业务处理逻辑对消费者组进行提前规划,避免为了方便将业务相关的topic同时划分到同一个大消费者组,这样一旦某个消费者出现问题,将会导致整个消费者组重新Rebalace。如果Rebalance时间过长,此时所有的topic无法消费,那么实时业务将会受到很大的影响。因此我们要合理分配topic到不同的消费者组。
监控
经过以上的探索分析,我们的首要任务应该是监控Kafka消费者组是否处于Rebalance状态,进而确定:
分区消费者是否发生切换,此时消费者数量不变;
分区消费者数量是否减少,出现一个消费者同时消费多个分区topic;
分区数量和消费者是否为1:1关系,避免出现消费者和分区数量不一致的情况;
1.监控思路
在多消费者组的情况下,我们不仅要监控每个消费者组的Rebalance的状态,还要考虑到未来消费者组的扩展,因此我们希望可以通过配置文件的形式对消费者进行自动发现并添加监控。在此我们仍然是通过Zabbix自动发现,实现对每个消费者组的Rebalance状态进行监控告警。
2.消费者组自动发现
由于此配置文件和Kafk topic监控复用同一个文件,通过Zabbix可对特定消费者组(Group)进行去重识别并行自动发现。
# 自动发现
vim consumer-groups.conf
#按消费者组(Group)|Topic格式,写入自动发现配置文件
test-group|test
# 执行脚本自动发现所有的消费者分组
bash consumer-groups-rebalance.sh discovery
{
"data": [
{ "{#GROUP}":"test-group" }
]
}
3.获取消费者组Rebalance状态
# 获取rebalance状态,0代表没有rebalance,1代表处于rebalance
[root#~] bash consumer-groups-rebalance.sh status test-group
0
4.最终脚本
#!/bin/bash
#comment: 查询消费者组状态,如果出现reabalance则进行告警
#配置文件说明,和topic lag监控共用一套配置文件
#消费者组|Topic
#test-group|test
#加载环境变量
export JAVA_HOME=/usr/local/jdk1.8.0_261
export JRE_HOME=$JAVA_HOME/jre
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
#group自动发现
group_discovery() {
printf "{\n"
printf "\t\"data\": [\n"
m=0
num=`cat /etc/zabbix/monitor_scripts/consumer-groups.conf |awk -F'|' '{print $1}'|sort|uniq|wc -l`
for group in `cat /etc/zabbix/monitor_scripts/consumer-groups.conf|awk -F'|' '{print $1}'|sort|uniq`
do
m=`expr $m + 1`
#判断最后一行
if [ $m -eq $num ]; then
printf "\t\t{ \"{#GROUP}\":\"${group}\" }\n"
else
printf "\t\t{ \"{#GROUP}\":\"${group}\" },\n"
fi
done
printf "\t]\n"
printf "}\n"
}
if [ $1 == "discovery" ]; then
group_discovery
elif [ $1 == "status" ];then
/usr/local/kafka/bin/./kafka-consumer-groups.sh --bootstrap-server 10.10.10.233:9092 --describe --group $2 > /tmp/$2 2>&1
cat /tmp/$2 |grep rebalanc |wc -l
else
echo "Usage: /etc/zabbix/monitor_scripts/consumer-group.sh discovery | lag"
fi
5.Zabbix自动发现
- 监控项原型 以消费者组定义监控项名称,告警信息中的名称能够帮助我们快速定位配置。
- 触发器配置 告警触发时,能够通过告警信息快速定位kafka 消费者组故障。
告警主机:Kafka_192.168.3.55
主机IP:192.168.3.55
主机组:Kafka
告警时间:2022.11.11 11:22:00
恢复时间:2022.11.11 11:23:02
告警等级:Warning
告警信息:消费者组test-group:处于rebalance状态
告警项目:group_status[test-group]
问题详情:
blaze-route: 1
其他运维问题简单处理
# 1.手动消费某topic积压的消息
/usr/local/kafka/bin/kafka-consumer-groups.sh --bootstrap-server 10.10.10.233:9092 --topic test --group test-group
# 2.调整kafka某个topic的数据有效期,有效释放磁盘空间
/usr/local/kafka/bin/kafka-topics.sh -zookeeper 10.10.10.233:9092 --topic test-group --alter --config retention.ms=79200000
# 3.调整kafka某个topic的分区数量
/usr/local/kafka/bin/kafka-topics.sh -zookeeper 10.10.10.233:9092 --topic test-group --alter --partitions 4
以上是在使用Kafka过程中比较常用的几个命令使用方式。