Flink内存参数调优

背景

Flink作业设置内存参数后发现不是自己预期的资源分配方式,比如分配了4G内存结果只用了2G,其余2G都是闲置的,导致Flink作业内存上限不够用,内存超用时TaskManager容器会被Yarn集群杀死。另外并行度与slot槽数在Flink on Yarn集群模式下如何设置才能资源利用最大化,在本文给出优化建议

 

Flink TM内存分配机制 

内存分配区域说明

  组成部分  

  描述  

框架堆内存

Framework Heap Memory

用于 Flink 框架的 JVM 堆内存(进阶配置)。

任务堆内存

Task Heap Memory

用于 Flink 应用的算子及用户代码的 JVM 堆内存。

托管内存

Managed memory

由 Flink 管理的用于排序、哈希表、缓存中间结果及 RocksDB State Backend 的本地内存。

框架堆外内存

Framework Off-heap Memory

用于 Flink 框架的堆外内存(直接内存或本地内存)(进阶配置)。

任务堆外内存

Task Off-heap Memory

用于 Flink 应用的算子及用户代码的堆外内存(直接内存或本地内存)。

网络内存

Network Memory

用于任务之间数据传输的直接内存(例如网络传输缓冲)。该内存部分为基于 Flink 总内存的受限的等比内存部分。这块内存被用于分配网络缓冲

JVM Metaspace

Flink JVM 进程的 Metaspace。

JVM overhead

用于其他 JVM 开销的本地内存,例如栈空间、垃圾回收空间等。该内存部分为基于进程总内存的受限的等比内存部分。

内存分配案例

设置(进程总内存) 

taskmanager.memory.process.size:4196m

设置托管内存分配比例

taskmanager.memory.managed.fraction:0.4 (默认)

taskmanager.memory.managed.fraction:0.2

自动分配区域

分配内存值0.4

分配内存值0.2

备注

Framework Heap Memory

128MB

128MB

 

Task Heap Memory

1.47G

2.16G

任务算子可用内存空间

(影响任务效率)

Managed memory

1.38G

704MB

状态缓存可用内存空间

(影响checkpoint效率)

Framework Off-heap Memory

128MB

128MB

 

Task Off-heap Memory

0b

0B

 

Network Memory

352MB

352MB

闲置内存空间

JVM Metaspace

256MB

256MB

使用少量内存空间

JVM overhead

420MB

420MB

闲置内存空间

申请、容器内存合计

4196MB

4196MB

 

设置(Flink总内存) 

taskmanager.memory.flink.size:4G

自动分配区域

分配内存值0.4

分配内存值0.2

备注

Framework Heap Memory

128MB

128MB

 

Task Heap Memory

1.80G

2.62G

任务算子可用内存空间

(影响任务效率)

Managed memory

1.64G

839MB

状态缓存可用内存空间

(影响checkpoint效率)

Framework Off-heap Memory

128MB

128MB

 

Task Off-heap Memory

0b

0B

 

Network Memory

420MB

420MB

闲置内存空间

申请内存合计

4196MB

4196MB

 

JVM Metaspace

256MB

256MB

使用少量内存空间

JVM overhead

495MB

495MB

闲置内存空间

容器内存合计

4947MB

4947MB

metaspace、overhead单独分配内存,不计入到申请内存中,容器内存会比预期申请的内存要大

案例分析

1、在相同的托管内存分配比例情况下,跟taskmanager.memory.process.size比较,设置taskmanager.memory.flink.size能申请分配更多的任务算子可用内存空间,因为JVM Metaspace、JVM overhead这两块区域空间不计入内存分配池子,额外算一部分内存(根据这两个参数的比例因子)

2、不管设置process.size还是flink.size,Network Memory、JVM overhead这两块空间都是闲置的内存空间,基本不会使用到,所以作业并行度和slot槽数设置越多(yarn集群下1并行度对应一个TaskManager容器),闲置内存空间会越多

 

实践总结

1、尽量设置taskmanager.memory.flink.size参数,能得到更多任务可用内存和托管内存

2、taskmanager.memory.managed.fraction托管内存分配比例这个参数只有在使用rocksdb状态存储情况下需要考虑设置成0.1~0.2值,使用hashmap可以设置更低,因为从实践来看基本不会用到这部分内存空间,目的就是尽可能的提高Task Heap Memory这块区域的内存可用空间,实践经验这块区域内存可用空间越大,Flink作业的吞吐量越大,作业的稳定性越高

3、TaskManager容器一般设置个3~4个就够了,更多的是提高任务可用内存空间的上限,在总内存相同情况下容器越多效率不一定高,容器多带来的网络IO消耗也更多

4、对于 YARN,如果 yarn.nodemanager.pmem-check-enabled设为true(公司集群已关闭) , 则会在运行时定期检查容器内的进程是否超用内存。如果进程总内存用量超出配额,容器平台通常会直接发送最严格的 SIGKILL 信号(相当于 )来中止 TaskManager,此时不会有任何延期退出的机会,可能会造成作业崩溃重启、外部系统资源无法释放等严重后果,所以没关闭这个检测前,提高容器算子任务可用内存上限很重要

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章