智汇 IT
城启新篇

实时计算任务的资源调优 一线踩坑攒的实操经验

上周去南京软件大道转了一圈,跟几个做流计算的工程师在园区便利店坐了俩小时,喝了三杯冰美式,十句话里有八句在骂资源配的不对。要么是预算卡的死,资源给少了天天崩,要么是一开始拍脑袋配多了,每个月账单出来财务追着问为什么实时计算的成本比离线数仓还高。绕来绕去,核心就是绕不开实时计算任务的资源调优这件事。

配多了烧钱,配少了雪崩

很多人刚接触实时计算的时候,最容易犯的错,就是把离线跑批的资源思路直接平移过来。

照着官方文档的推荐值往上堆,甚至直接把跑批任务的配置复制到实时任务上。

这坑踩的人太多了。

之前碰到个做用户行为实时分析的团队,刚上Flink的时候,照着文档给每个TaskManager配了8G堆内存、2核CPU,跑了一周算下来,成本比离线数仓的同规模任务高三成,关键还经常出checkpoint超时的告警。

Flink实时任务资源监控面板截图
Flink实时任务资源监控面板截图

说白了,实时任务的资源消耗逻辑跟离线根本不是一回事。离线是攒够一批数据再算,峰值和谷值差个十倍都正常,算完就释放资源。实时任务是7*24小时挂着,流量跟着用户行为走——早高峰、午间刷手机的时段、晚高峰、零点流量掉下来,处理负载的曲线晃得跟过山车似的。

你照着峰值配资源,谷值的时候一半CPU和内存都在空转,钱纯白花。

你照着谷值配资源,高峰一到直接背压打满,checkpoint做不完,数据延迟从秒级涨到分钟级,甚至直接任务挂掉,告警群直接炸锅。

钱不是这么省的。

也不是这么花的。

别上来就堆资源,先摸清楚消耗的真实构成

大部分人调优的第一步就错了。

上来就盯着监控面板上的CPU使用率、总内存占用,觉得数值低了就加,高了就减,根本没拆过这些资源到底被谁吃了。

实时任务的资源消耗根本不是一个整体。就拿堆内存来说,里面有多少是给用户代码创建的对象占的,有多少是网络传输的缓冲占的,有多少是RocksDB的本地块缓存占的,甚至有多少是代码没写对攒的垃圾——之前碰到个任务,跑了三天内存从2G涨到16G,重启就掉回2G,最后查了半天才发现是代码里把所有用户访问日志都存在一个静态Map里,根本没做过期清理。

很多人第一反应是,那把堆内存调大点,给用户代码留足空间不就完了?

代价是什么?堆越大,垃圾回收的停顿时间就越长。本来实时任务要求的是毫秒级的处理延迟,一次Full GC停个两三秒,所有正在处理的窗口数据直接堵在管道里,延迟直接打穿SLA。

那把堆调小?又容易触发OOM。

这个度其实没那么难拿。先跑一周的小流量灰度,把每类资源的实际占比拆出来——用户代码实际占多少,网络交换占多少,状态后端占多少,剩下的冗余留个20%足够了,别上来就留一倍的冗余,纯纯浪费。

Flink任务内存分层结构拆解图
Flink任务内存分层结构拆解图

这事没那么玄。就像你给不同的人配饭量,干体力活的要多吃米饭,坐办公室的要多吃菜,总不能不管啥任务,上来就给一样的配置。做实时数仓维度关联的任务,要跟HBase、Redis频繁打交互,网络带宽的消耗比纯计算的任务高一大截,你给配的网络带宽不够,哪怕CPU内存剩一半,照样出反压。做实时特征计算的任务,状态特别大,全存在RocksDB里,你给的本地磁盘IOPS不够,每次checkpoint往磁盘刷数据的时候,直接把IO打满,延迟蹭蹭涨。

动态弹性不是万能解药

最近这两年各个云厂商都在推实时任务的弹性伸缩,说什么自动根据流量调整资源,既省成本又稳。说实话,刚出来的时候我也觉得这东西是神器,直到跟几个实际落地用过的团队聊完,才发现坑真不少。

弹性伸缩的触发是有滞后的。你想啊,流量从涨上来,到监控系统采集到指标,判断需要扩资源,然后申请新的TaskManager,拉镜像,启动,把对应的状态从老的节点迁移过去,整个流程走下来快的要一两分钟,慢的要五六分钟。这时候早高峰的流量早就冲进来了,老节点早就背压打满了,等新节点上来,数据已经攒了一大堆,延迟早就过了用户能接受的阈值。

那怎么办?把弹性的触发阈值设的特别低?比如CPU到30%就开始扩,那跟你固定配足够的资源有啥区别?成本根本降不下来。而且状态迁移的时候,本身就要占额外的网络和IO资源,本来流量高峰就忙,你还要分资源去迁状态,相当于堵车的时候还要在路上掉头找停车位,越搞越乱。

麻烦在于,很多团队刚上弹性的时候,根本没摸清楚自己的流量规律,上来就把所有参数拉满,结果每次流量波动的时候,集群里的节点增增减减,光状态迁移的成本就比固定配资源还高。

之前有个团队,把所有实时任务都开了全量自动弹性,本来想省30%的资源成本,结果上个月大促的时候,流量比平时涨了三倍,弹性触发慢了半拍,三个核心任务直接延迟了四十分钟,最后算下来赔出去的用户权益,比之前一整年的资源成本都高。

那弹性到底怎么用才对?把它当兜底的工具,不是全靠它。平时的固定资源,配到能覆盖80%的日常流量就行,剩下20%的突发流量,靠弹性来补,而且要把伸缩的冷却时间设短点,别等流量都过去了才反应过来。还有,别拿弹性当内存泄漏的遮羞布——之前有个任务,内存慢慢涨,弹性系统觉得是流量涨了,不停的加节点,最后排查发现是代码里的引用没释放,加再多节点也没用,越烧钱越卡。

很多人调优的时候,总想着找个大牛给个最优解,花大价钱请外部专家,上来给你调几个冷门参数,说这个配置改了性能能提一倍。实际上呢?大部分场景下,你把最基础的事情做好——把资源消耗的构成拆明白,把冗余留够,把代码里的小问题修一修,比你改十个冷门参数都管用。

之前碰到个团队,折腾了半个月,翻了几十篇参数调优的文章,改了二十多个Flink的配置,最后发现任务延迟高的原因,是他们把checkpoint的间隔设成了10秒,每次checkpoint的时候都要把所有状态刷一遍磁盘,磁盘IO直接打满,把间隔改成30秒,延迟直接降了80%,啥别的参数都没动。

前几天跟那个在软件大道碰到的工程师唠完,他说准备下周把所有实时任务的配置重新过一遍,把空转的资源砍一半,把经常OOM的任务的内存重新拆解开配。我说你这么搞完,每个月能省出大几万的服务器成本,还能少收点半夜的告警。他笑了笑说,能睡个整觉比啥都强。

免责声明:市场有风险,选择需谨慎!此文仅供参考,不作买卖依据。如有侵权请联系删除。
文章名称:实时计算任务的资源调优 一线踩坑攒的实操经验
文章链接:https://m.itcdj.com/it/302.html