(线上问题十二)网络故障引起kafka客户端无法消费问题
Posted 重庆JAVA圈
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(线上问题十二)网络故障引起kafka客户端无法消费问题相关的知识,希望对你有一定的参考价值。
这个问题最早出现在一年前,最近才完全解决。
故障现象:
当集群的网络发生故障后或换磁盘,kafka客户端程序报错:协调器死亡,groupID xxx 无法加入,从而导致客户端无法访问kafka。等待五到十分钟后,更换groupID重启服务端,服务恢复正常。
故障分析:
通过查询分析日志信息,初步判定为kafka服务端的coordinator模块异常导致。
coordinator模块功能介绍:
kafka0.9.x版本开始,采用groupcoordinator模块负责对consumer进行管理,包括offset的记录,同一个consumer group中不同consumer与partition的对应关系的分配等工作。
每一台broker上都有groupcoordinator服务器,而且通过内部topic __consumer_offsets来存储消费者的消息信息,每个consumergroup确定其group coordinator的方式为:用 consumer group 的名字的 hashcode 对__consumer_offsets 的分区数取模,得到一个分区编号,然后这个分区的 leader 在哪台 Broker 上,哪台 Broker 就是这个Consumer Group 的 GroupCoordinator。比如现在__consumer_offsets 分为50个 topic ,然后你的 consumer group name 是 usercenter , hashcode 是2036233184,对50取模为34,34就是__consumer_offsets 的分区 id ,然后__consumer_offsets 的 replicas 是3,假设34这个分区落在1, 2, 3这三台 broker上,然后1是这个分区的 leader ,那么 usercenter 这个 consumer group 的 GroupCoordinator 就是1这一台。
内部topic(__consumer_offsets)的数据存储格式为:topic+groupID+partition+offset,默认情况下,该集合会采用compact方式进行数据压缩(其压缩方式可简单理解为以topic+groupID+partition为value哈希出offset这个key,只保留key值大的数据),删除老的offset,只保留最新有效数据,从而保证该topic的数据保持在一个较小的水准。当某台broker出现异常时,会触发__consumer_offsets分区leader的切换,切换时,新的leader必须将该分区的所有数据加载完成后,才会对外提供服务。
故障现场分析:
当网络发生故障时,网络异常超过了集群的超时机制,导致集群发生了切换,客户端正常发送了request请求,并获取了对应__consumer_offsets的leader分区信息,但对应的coordinator并未正常返回响应信息,通过分析该服务器的文件及日志信息,发现该分区对应的__consumer_offsets文件多达300G,且broker日志也未出现完成load该__consumer_offsets分区的信息,因此基本可判定其原因为__consumer_offsets文件太大,broker发生切换时加载__consumer_offsets分区信息耗时太长,从而导致前端服务长时间无法恢复。通过进一步分析,__consumer_offsets文件过大的原因是配置文件中log.cleaner.enable参数为false,集群未启动自动清理策略。
恢复方式:
1、修改集群配置信息,将log.cleaner.enable参数修改为true,并重启集群,参数生效。
2、由于当前__consumer_offsets的数据量太大,完全依靠集群自身的清理策略,开销较高,可通过手动删除__consumer_offsets中老的segment的方式,适当降低__consumer_offsets的数据量,然后再依靠集群自身的清理策略清理数据。
这个问题以前一直在可以参看,之前的都只治标不治本。
关注重庆java圈
以上是关于(线上问题十二)网络故障引起kafka客户端无法消费问题的主要内容,如果未能解决你的问题,请参考以下文章
MySQL从入门到精通50讲(四十二)-线上环境MySQL Last_Errno:1292故障解决方案