Debezium Mysql BinLog同步引擎的内存爆满,频繁GC导致CPU爆高

现象,第一步

同步任务的http接口查询任务列表接口突然变卡,很久才相应,进入服务器后执行top命令发现CPU已经爆满。

top (查看进程占用资源)

机器是4核,所以占用了400%

wecom-temp-138912e7f885f37ae16b86cb7872acc1.png

top -H -p 276965 (查看进程ID下的子进程占用资源)

4个子线程,每个各占了100%

wecom-temp-06673636548e93c8a3584ee412ca405c.png

printf “%x\n” 276970

jstack 276965 | grep 439ea -A 100

通过查看当前线程执行的详情,发现输出的是gc线程

jmap -heap 276965

jmap的使用方式:blog.csdn.net/heihaozi/ar…

查看jvm当前的堆内存情况,老年代、新生代皆已满

wecom-temp-9498631e96940ca4b078158f017e544a.png

上面的命令具体怎么用参考这篇blog:blog.csdn.net/cainiao1412…

第二步

既然是堆内存满了,此刻就要拿到整个堆内存的快照,执行

jmap -dump:live,format=b,file=heap.dump 276965

下载到本地使用 VisualVM 打开,有很亮眼的TableMapEventData,但是此时还是不清楚何处引起的泄露。

VisualVM的使用方式:blog.csdn.net/weixin_4546…t.zoukankan.com/wangzun-p-1…

image.png

此时使用工具MAT继续打开dump,这里看就比较明显,是一个名为MySql…EventSource类中的tableMap…ByTableId的一个HashMap巨大,

MAT的使用方式:zhuanlan.zhihu.com/p/482860374 , blog.csdn.net/w2009211777…

image.png

第三步

根据MAT的提示,找到该处代码,可以看见在收到TABLE_MAP这个Event事件时,会将数据放到HashMap中

image.png

数据既然存,就也需要清理,在源码中只找到了一处清理该Map的地方,当收到ROTATE事件时,清理Map,那么由此可见如果不收到ROTATE事件,Map将会无限增长

image.png

什么是ROTATE事件?

参考:www.freesion.com/article/125…

也就是说我们的Map会等到binlog文件大小达到 max_binlog_size 的值时,才会进行清空,或者手动执行flush logs,但是生产环境中一般不会去手动执行,max_binlog_size 的值我们的库默认为 256MB。

image.png

什么是 Table Map Event?

意思就是 Table Map Event 会存储表的元数据,例如数据库名、表名、字段等,后续的Row Event会通过table id 和其关联,取到对应的元数据,因此这个存储是有必要的,

但是table id会随着缓存淘汰、刷新等机制出现变化,也就是说同一个库的同一个表的table id会不停的变化,因此table id并不是唯一的,所以我们的Map会随着程序的运行可能存储很多明明是同库同表,但是因为table id不同导致存map中很多重复的数据,导致占用内存越来越大。

image.png

image.png

解决方式

Debezium对mysql binlog同步默认使用的是 github.com/osheroff/my… , 这个库很久没有更新了,

但是Flink CDC使用的也是 Debezium,也就是说也依赖了这个库,所以可能也会存在这种问题,

两种解决方式,一是增大内存,均匀任务,让内存足够存储这么多的冗余数据,二是修改源码,在特定时机,例如新的table id过来时,将老的table id对应的数据清除?

针对binlog的同步,还有一个工具叫做maxwell,在生产环境中使用并没有出现这种问题,追踪了一下源码,也是类似的原理,但是maxwell使用我们使用了docker做资源隔离,每个进程给了2g,而Debezium任务则跑在同一个jvm中,因此更多倾向于均匀分配一些资源。

最终解决方式

我们的系统采用的版本是1.9.0.Final,在查看其源码时,在 MySqlStreamingChangeEventSource 类中,针对 ROTATE 事件发生时,并没有对map进行clear处理,所以导致了内存泄露,为了避免升级版本影响过大,我们采用了修改源码的方式,针对ROTATE发生时,对map进行清除。

在这里插入图片描述

在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值