Flink集群CPU-LOAD抖动问题排查
故障经过
月8日 22点左右 线上flink集群开始报警,经查看 部分节点load搞达100+,CPU 100%耗尽,
通过top命令查看cpu情况找到耗费CPU的进程,然后根据进程ID 找到此进程的相关信息,发现是直播业务方昨天新提交上来的flink任务的task进程。然后又查了一下此任务的GC情况,如下
很明显内存不够用了,频繁触发FULL-GC,最终引发cpu抖动,占内存且无法回收的直接能想到的就是窗口中的STATE,那么大小怎么看呢,flink里有个比较方便的办法,就是通过UI界面直接查看这个任务的checkpoint大小,我们看了一下这个任务的checkpoint的大小,大约是1G(图忘截了,就不放了)。情况比较明显就是这个有点大了,导致内存不够了
为了快速恢复故障,当时也没多想,直接采用了最粗暴的方式,将STATE从内存改用rocksdb,让业务方修改完代码之后重新发布上线
观察了一下,情况明显好转,但是负载还是稍微有点高,跟业务方交流了一下,这个任务每秒数据量只有几百条,讲道理这么小的数据,不应该有这么高的负载才对,而且网卡流量也有点高,
好吧虽然现在集群是稳定住了,但是这个任务为什么耗那么多资源呢?现在不急了,我们慢慢排查一下
我们先看了一下网卡流量,网卡流量真的比较大,如图
我们又执行了CPU分析脚本(我们公司内部用的专门分析CPU占比线程以及代码堆栈的脚本),结果如下
看了一下 吃CPU的基本都是这个代码堆栈,通过代码堆栈,很明显能看出来,这个是写checkpoint到hdfs,这玩意为什么写的这么猛?除了checkpoint比较大之外(1G左右),估计也是写的太频繁了,跟业务方协商后,把他们的代码拉下来看了一下
果然5秒一次,让业务方把间隔改成10分钟试试,改之后重新发布上去,系统负载瞬间小了很多,但是每10分钟,仍然会有一波峰值(写checkpoint)
好了,到这系统负载是基本下来了,但是问题还未彻底解决,现在可以静下心来去看看为什么checkpoint这么大了,了解flink的朋友应该知道STATE在每个窗口里都会存在,既然这个数据量应该不大,那么就可能是窗口太多了,带着这个问题,我们执行了一下 jmap -histo 看了一下,果然不出所料
看过源码朋友应该都知道这个TimeWindow就是窗口,1600万个窗口,WAHT?疯了吗?没办法找业务方交流了一下,一起review了代码,他们的窗口设置是30分钟的滑动窗口,滑动步长是10秒,这样的话窗口就比较多了,另外最关键的是,他们为了统计进入直播间的userId的进出次数,对userId进行了group by,而userId不用想也知道非常非常多,大致处理SQL如下
SELECT utc2local(TUMBLE_END(rowtime, INTERVAL '20' SECOND)) as atime, roomId, sum(fnMin(c, 10)) as num FROM
(
SELECT
HOP_ROWTIME(rowtime, INTERVAL '10' SECOND, INTERVAL '10' MINUTE) as rowtime, roomId, userId,
count(*) as c
FROM
30
GROUP BY
HOP(rowtime, INTERVAL '10' SECOND, INTERVAL '10' MINUTE), roomId, userId
) GROUP BY
TUMBLE (rowtime, INTERVAL '20' SECOND), roomId
好了一切谜团都解开了,让业务方修改代码逻辑,不要再 gourp by userId了,通过别的方式进行进出直播间次数统计。一切又归于平静
蘑菇街-无情 发布了6 篇原创文章 · 获赞 1 · 访问量 169 私信 关注