记一次生产环境Flink内存调优(调整)的过程

前言

生产上线一个任务,稳定运行中,突然,挂了。查看报错为oom了,本着内存不够那就加资源的原则(本人代码并无明显问题,哈哈哈),那就给tm的内存多一点就完事了。

最开始给的资源参数在提交命令中是这样的

-Djobmanager.memory.process.size=800mb
-Dtaskmanager.memory.process.size=2048mb

其中,tm的执行内存给了2g,我觉得怎么也够用了,结果发现还是oom了。可能确实程序处理的数据量有点大,而且还使用了开窗。别的程序tm给1g就可以了,一直运行也无问题,这个程序特殊。

开始我理解的有问题,觉得2g,内存怎么也行了,但是实际上,flink有自己的一套内存模型,有自己默认的分配策略,虽然我们给了2g,但是实际上程序处理能用的内存,也就是task heap,并没有很多。

先说下我调整之后的结果,我一怒之下tm直接给了4g,然后观察tm如下

会发现,虽然tm给了4g的内存,实际我们业务代码在进行数据处理时候用到的内存却只有1.42g

真特么坑。。。

调节过程

打开flink的官网,看下flink内存模型的介绍,地址如下

Set up TaskManager Memory | Apache Flink

flink的内存模型图如下

其中每一部分的内存都是怎么分配的,怎么计算的,有无默认值,给谁用的,这里不做详细的介绍,可以直接看flink的官方文档。这里说一下我是怎么调节的

原先的启动参数变成了如下

-Dtaskmanager.memory.process.size=3072mb
-Dtaskmanager.memory.task.heap.size=1536mb
-Dtaskmanager.memory.managed.size=512mb

因为我的flink程序并不需要使用那么大空间的托管内存,也就是managed memory。所以我这里是手动给了一个固定大小的值,然后flink的处理总内存给了3g,又因为程序对task heap使用的比较多,我直接给了一半1.5g,让其对资源进行充分的利用。其他部分的内存,flink会根据内存模型,自动的进行划分和分配。有些是直接使用的默认值,有些是按照比例给定的。

参数调整之后,再次运行flink作业,打开tm如下

调优之后的flink内存模型,在task heap处使用的我们指定的内存大小,重点是托管内存,我们手动指定了,而不是flink自动分配了,不再需要那么多的资源,而且整体内存才3g,比起我们直接设定tm运行总内存4g,还省了1g的资源。而且实际的task heap内存并不受多大的影响。

总结

这里只是针对我的flink作业,做的内存调整优化,因为我的flink作业对于托管内存使用并不大,所以我可以这样设定,各位的flink作业未必。想说的就是,各位根据自己的flink作业去灵活的调整各个部分使用的内存大小,要对照各自的flink作业和业务了解这个内存是干什么用的,根据数据量预估大概使用多少量,必要时要进行压测。在设定的过程中,整体上一定要遵守flink的内存计算规则和约束,这些在官网的介绍中都有。

最后,祝各位flink作业不挂,并且在调优的道路上越走越远。。。

### Flink SQL性能方法与最佳实践 #### 1. 合理配置状态后端 为了提升Flink SQL作业的性能,合理配置状态后端是非常重要的一步。状态后端的选择直接影响到系统的吞吐量和延迟表现。通常情况下,推荐使用RocksDB作为分布式环境下的状态后端,因为它能够很好地应对大规模的状态存储需求[^3]。 #### 2. 使用JOIN_STATE_TTL化双流连接 从VVR-8.0.1版本开始,Flink SQL支持通过`JOIN_STATE_TTL`提示为左流和右流分别设置不同的生命周期。这种机制允许开发者根据实际的数据流动态调整状态保留时间,从而显著降低无用状态带来的额外负担。例如,在执行复杂的多表联接时,可以通过如下方式指定TTL参数: ```sql SELECT /*+ JOIN_STATE_TTL('left_table' = 'INTERVAL \'1\' DAY', 'right_table' = 'INTERVAL \'2\' HOURS') */ * FROM left_table LEFT JOIN right_table ON ... ``` 这种方式不仅减少了内存占用,还提高了整体计算效率[^2]。 #### 3. 共享状态实例减少冗余 当涉及到多个`COUNT DISTINCT`操作时,如果它们都基于相同的列,则可以考虑利用过滤条件共享同一个状态实例。具体来说,就是让所有的聚合函数尽可能复用已有的中间结果而不是单独创建新的状态对象。比如下面这个例子展示了如何通过组合不同filter条件来达到目的: ```sql SELECT a, COUNT(DISTINCT b) AS total_b, COUNT(DISTINCT b) FILTER (WHERE c IN ('A', 'B')) AS AB_b, COUNT(DISTINCT b) FILTER (WHERE c IN ('C', 'D')) AS CD_b FROM T GROUP BY a; ``` 上述查询逻辑表明,只要满足一定条件下(即作用于相同字段),就可以共用单一状态结构完成多种统计任务,进而削减总体消耗并加速响应速度[^4]。 #### 4. 资源分配建议 除了技术层面之外,硬件资源配置同样不可忽视。一般而言,启动TaskManager时至少应为其预留1CPU核心以及4GB RAM空间;当然这只是一个基础指导原则而已——考虑到现代云计算环境中普遍采用的是虚拟化资源池模式,因此按照此标准规划往往可以获得较为理想的平衡效果。另外值得注意的一点是要形成良好的运维习惯,定期监控集群健康状况以便及时作出相应调整[^5]。 ```python # 示例Python脚本用于动态修改Flink配置文件中的parallelism参数 def update_flink_config(config_path, new_parallelism): with open(config_path, 'r+') as f: lines = f.readlines() found = False for i,line in enumerate(lines): if line.startswith('taskmanager.numberOfTaskSlots'): lines[i]="taskmanager.numberOfTaskSlots: {}\n".format(new_parallelism) found=True if not found: lines.append("taskmanager.numberOfTaskSlots: {}\n".format(new_parallelism)) f.seek(0) f.writelines(lines) update_flink_config('/path/to/flink-conf.yaml', 4) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值