记录一次kafka百万消息堆积的处理过程

业务背景可以详见上一篇文章:通过kafka,canal进行数据异构同步的一套技术方案_赞的心路历程-CSDN博客

2021年10月25日开始,业务大爆发,数据量激增 ,到了28日zabbix监控显示差不多堆积了90万的消息

通过skywalking查看消费者的消费吞吐量并没有异常,是业务数据大爆发,造成了日数据增量成倍增加,消费不及时

,造成了消息堆积。

逐步排查消费瓶颈在何处:

将涉及到的服务资源按,kafka,消费者,目标数据库的cpu,内存,硬盘,带宽,逐一排查;

首先因为完全是内网操作,带宽不会达到瓶颈,排除。

在查看了kafka,消费者之后,它们的cpu,内存,磁盘io均处于正常值

通过阿里云数据库监控发现异常

可以看到数据库IOPS长时间处于100%的状态,数据库性能抗不住了。排查该数据库是否有某些慢sql,经过一波慢sql优化后,但情况并未明显改善,此时数据库硬件版本内存16G,紧急进行扩容申请,发起64G内存版本的数据库资源。

在申请期间,消息堆积量越来越大,开始尝试想其他办法,为数据库升级后消费者的消费性能能够大幅提升。

当前kafka分区6个,消费者节点6个,一个消费者对应一个分区,尝试增加kafka分区,增加消费者节点,申请服务器资源。

为了提高消费性能,在资源未下来之前,进行codereview排查是否可以进行某些业务代码的改造。

通过skywalking的链路追踪功能,观察一条消息的链路轨迹,发现消费者的业务逻辑中绝大部分都是毫秒级的执行过程,但有一个方法进行了远程http调用,会超过1秒,通过讨论,决定该方法可以异步多线程执行,并不会影响到结果,于是改代码,发版,(因为数据库资源还未下来,瓶颈还在,无法明显观察到消费能力的提升)。

开始商讨是否可以先将入口关闭,尽可能将已堆积的消息消费完。而且还有一个问题存在,kafka的消息分区极不平衡,堵塞在指定的两个分区,其余四个分区未堵塞,结合业务背景,使用的是主键hash分区,而数据提供方的主键id均是uuid,通过hash操作后结果集不平衡(无法修改第三方数据,一开始提出id采用分布式id,但是无果)。

此时已是10月29日凌晨,在关闭数据的入口后,缓慢消费存量消息。

10月29日下午,数据库资源升级成功

可以观察到IOPS大幅度下降,只有极个别时间点会超过100%。阻塞消息量也开始可观察的下降,但是想要消费完存量消息时间不允许,甲方要求数据统计至31日11点,下午1点50出统计结果。而此时只是存量消息在消费,29日的实时消息并未进来,以及30日,31日的数据量会更大,需要考虑更多的优化方案。

商讨扩容方案:

方案一:是否可以将已有的6个消费者节点只做消息转发操作,将消息转发至另一个高性能kafka中间件,再新启n个监听新kafka的消费者节点,进行消息消费操作,(服务资源有限,高性能kafka中间件,以及消费者节点无法理想的部署n多个),并且这套方案会对数据更新的顺序产生影响,会导致脏数据。

方案二:是否可以将新数据发送至新的Topic,重新进行分区,这样原先的6个消费者消费存量数据,新数据通过新部署的消费者消费,这个方案同样会会对数据更新的顺序产生影响,会导致脏数据。

这时候,观察到数据库的连接数使用率不高,是否可以增加消费者连接池最大连接数来提高消费能力。

消费者工程使用的是druid连接池技术,spring.datasource.druid.max-active 的值是默认值8,将它提高一倍,设置成16,发版观察,消费能力并未提升。

同样通过修改消费者 MAX_POLL_RECORDS_CONFIG 的kafka配置参数,消费能力也并未提升。

在甲方以及用户一次次的询问进度,时间来到了30日,服务器资源终于下来了,可以增加消费者节点了。

在进行kafka消息重新分区过程中,会导致部分消息错乱,但是尚未考虑到更完美的方案,只能记录时间节点,稍后进行手动核对,进行数据最终一致性确认修复。

将kafka原先的6个分区,修改为12个分区,消费者节点也由6个维护为12个

通过zabbix可以观察到即使在开启同步的情况下,堆积的消息也在下降,虽然可能偶尔业务数据量大爆发,会造成堆积消息变多,但是12个消费者节点抗住了流量峰值,通过简单计算可以完成甲方的需求。

时间到了10月31日11点左右,发现目标库的数据业务时间节点已经很接近11点,也就是说此时可以进行相关的统计计算了,开始手动补录一些丢失数据,在13点左右消费的消息数据业务时间均是11点之后的,可以进行相关统计计算,于是乎,手动开启xxl-job进行分片定时任务,计算。终于在13点51分,得到一份经过核对,达到准确性要求的统计结果,报告甲方。(后记:11点后的业务堆积数据一直到17点左右才真正消费完,做到消息的实时消费)

最后心得:

1、甲方有时候为了节约成本,服务资源总是不够用,所以需要提前想好对策

2、在有限的资源内,需要考虑更多的可行性方案解决问题,克服种种困难

3、在性能优化上需要从多角度考虑,大胆假设,小心求证

4、熟悉并部署多种监控手段,及时了解性能瓶颈在何处

Guess you like

Origin blog.csdn.net/dyangel2013/article/details/121084112