kafka大量堆积故障复盘(生产环境)

Posted 终成一个大象

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kafka大量堆积故障复盘(生产环境)相关的知识,希望对你有一定的参考价值。

kafka大量消息堆积故障复盘

一、前言

这个事是上个老东家遇到的,我是一个旁观者的角度目睹整个故障的产生和修复,过后也未进行总结复盘。最近吧,自己被安排解决kafka重复消费的一些问题,就想起来这个事,索性就把整个事件进行一个回顾,另外也把kafka大量消息堆积的处理方案也进行总结归纳,这个问题还是比较常见的。

二、过程复盘

某一天晚上,公司某一个程序员写的某一个程序挂掉了,服务呢也没有被重新拉起来。这个服务的逻辑并不是很复杂,主要是消费kafka消息并计算出一个数据,但并发量很大,每天有大概几百w的量级。

这个服务挂掉后,kafka集群的消息就一直开始堆积,到第二天来到公司后发现,大概一共堆积了200w的消息,重启服务器后,发现以服务的消费速度要完全消费掉所有的堆积数据也需要1天多,这么多的数据很明显不能让他持续堆积着,一个是影响最新数据的处理,另外也占用多余的资源。

所以我们技术部的大leader提出了一个解决方案,新增一批5个消费者和5个kafka分区,这些消费者的主要功能是消费数据并入库存储(临时开发),一个消费者qps为500,5个消费者一分种的吞吐量为500 * 60 * 5 = 15w,200w堆积消息20分钟内能解决掉。当然这只是第一个步骤,这个步骤完成后可以保证生产环境正常工作。

第二个步骤,解决这些未消费的消息。正常情况下,我们的消费者的吞吐量远大于生产者的吞吐量的,我们只需要把再写一个服务:把临时存储的200w堆积消息,以不会产生堆积的速度再次生产到kafka集群中,让消费者消费掉就可以了。

三、总结

懒的画图了,贴个还算清晰的kafka的架构图:

1、产生原因

  • consumer意外down机
  • consumer吞吐量低于producer
  • partition分区过少
  • consumer处理超时,导致频繁rebalance

2、解决方案

2.1、优先处理堆积数据,恢复生产环境

  1. 增大partition个数
  2. 增加消费者数量
  3. 消费堆积数据入库保存
  4. 减少consumer处理时长
  5. 避免产生rebalance

注意:
同一个消费群组的consumer个数要等于partition个数,这样能让consumer的消费能力提升到最大。

同一个topic下的partition和sonsumer对应关系:

2.2、处理堆积数据

  1. 非时间敏感数据,读库并生产到消费队列。
  2. 时间敏感数据,梳理业务影响,采取能保证数据一致性的方案,如手动导入、重新构造等等。

参考链接:
Kafka 消费者与消费组
如何处理大量积压消息

公司内部一次关于kafka消息队列消费积压故障复盘分享

公司内部一次关于kafka消息队列消费积压故障复盘分享报告。总结现象,分析原因,给出了具体解决方案...

背景现象

1.20晚上8点业务线开始切换LBS相关流量,在之后的1个小时时间内,积压量呈上升趋势,一路到达50W左右,第二天的图没贴出具体是50W数字,以下是第一天晚上的贴图部分。

现象一:

 

现象二:

当时现场图后来就找不回来了,凭印象说明了一下数字。

 

 

简要说明一下上述两个图

 

图一:其实很明显,明显看出,消费者消费速度明显跟不上生产者的发送速度,导致出现积压情况。

图二:图二就有点意思了,因为上游通过Kafka消息队列发送消息给我,topic对应的分区数是20个。由于我的应用消费组内消费者实例是17个,所以从宏观上分析,势必会有3个消费者会承担多消费一个分区的情况。这个倒也容易理解。但为什么会积压这么多。个人分析了一下,主要还是跟消费者本身消费的消费业务逻辑有关。因为我的消费业务逻辑是要调用下游一个LBS地图服务的,通过设备上报的WIFE内容经过公司LBS平台接口换取设备当前地理位置坐标信息,但这个地理位置服务,R通过命令:thread-n3-i 500 : 列出500毫秒内最忙的3个线程栈,其中就有两个属于调用地理位置服务的线程。

 

 

通过命令:thread-n3-i 500(阿里开源诊断工具Arthas:thread命令) : 列出500毫秒内最忙的3个线程栈,其中就有两个属于调用地理位置服务的线程。

 

 

原因分析

 

分析了具体原因具体是两个层面

  1. HMS-Client(公司自己封装的调用消息队列的SDK)层面

根据图一,其实想说明一点的是,在本应用调用下游服务延迟高的场景下,从图一的现象看出,消费者的利用率其实不高,topic有20个分片,消费组17个容器实例,14个实例基本对应一个分区,有三个实例对应2个分区,导致资源利用率其实很低,而我们其实是希望在下游服务相应慢的情况下,最好有更多线程参与去消费任务,增加吞吐率,提高处理效率(IO密集型应用,尽量提高处理线程数)。而我们的处理线程数是5个,即最高5个线程会去处理任务,其他都会等待进入

 

 

这两个参数,当下应用设置了5个,但我的机器配置是8核16G,参数设置是不合理的。这个参数主要是从其他项目中拷贝过来,没过多关注他,在高并发应用场景下,想不多却成为瓶颈,特别是消费线程内如果涉及到RT很高,QPS上不去的下游服务,就有讲究了。

  1. 调用下游服务响应延迟高

这个我上述图二已经有详细描述了

 

解决方案

  • 调整Client 消费线程数,从原来的5调整到20个线程
  • 增加KAFKA的分片数,临时方案,目前已经让中间件从原来的分片数20调整到60,积压下降的明显。因为消费组内的消费者实例一个承担了基本3-4个分区消息数。

以上是关于kafka大量堆积故障复盘(生产环境)的主要内容,如果未能解决你的问题,请参考以下文章

生产环境一键创建kafka集群

kafka简单回顾

flink处理数据从kafka到另外一个kafka

生产故障|Kafka ISR频繁伸缩缩引发性能急剧下降原因分析

生产故障|Kafka ISR频繁伸缩缩引发性能急剧下降原因分析

生产故障|Kafka ISR频繁伸缩缩引发性能急剧下降原因分析