其實官方文檔中的對於Flink內存模型講解的已經很詳細了,本文主要是介紹下個人對這個內存模型的理解,如果有理解不對的地方,希望大家幫忙指正下!因爲接觸Flink的時間比較晚,所以一上來我們使用的就是V1.10版本,TaskManager的內存模型與配置在該版本中做了很大的優化。
Flink 1.10之前的的內存模型存在的缺點:
1. 流處理與批處理內存配置方法不同。比如Managed Memory這塊內存,在批處理中有用,在流處理中使用不到的
2. 內存配置細節繁多,概念比較難懂,比如容器化會有專用的cutoff內存
3. RocksDB狀態後端的內存不好配置(這部分個人沒有理解,因爲我們是使用的HDFS,沒用RocksDB…)
個人對V1.10版本之前的內存模型只是想有個簡單的瞭解,不打算做深入的研究了,反正我們項目中後續使用的都是V1.10之後的版本...
Flink 1.10版本內存模型:
Flink1.10版本內存模型架構如下圖所示:
Total Process Memory(進程總內存)包含了Flink應用程序使用的全部內存資源:Total Flink Memory(Flink應用使用的內存) + 運行Flink JVM使用的內存。Total Process Memory對應Yarn/Mesos等容器化部署模式(需要用戶指定),相當於申請容器的大小,Total Flink Memory對應standalone部署模式(需要用戶指定)。
Total Flink Memory內部分成了:堆內內存 + 堆外內存:
堆內內存包括兩部分:FreameWork Heap Memory(框架堆內存) + Task Heap Memory(任務堆內存)
堆外內存包含三部分:Managed Memory(託管內存) + Framework Off-heap Memory(框架堆外內存) + Network Memory(網絡內存)
官網已經總結的很詳細了:
組成部分 |
配置參數 |
描述 |
默認值 |
框架堆內存(Framework Heap Memory) |
taskmanager.memory.framework.heap.size |
用於 Flink 框架的 JVM 堆內存(進階配置)。 |
默認128M,不建議修改 |
任務堆內存(Task Heap Memory) |
taskmanager.memory.task.heap.size |
用於 Flink 應用的算子及用戶代碼的 JVM 堆內存。 |
無默認值 不建議配置,Flink框架會使用Flink總內存-堆內框架內存-網絡內存-託管內存得出。(按照默認值,肯定低於Flink總內存的50%) |
託管內存(Managed memory) |
taskmanager.memory.managed.size taskmanager.memory.managed.fraction |
由 Flink 管理的用於排序、哈希表、緩存中間結果及 RocksDB State Backend 的本地內存。受限Flink 總內存 |
無默認值 比例默認爲0.4 |
框架堆外內存(Framework Off-heap Memory) |
taskmanager.memory.framework.off-heap.size |
用於 Flink 框架的堆外內存(直接內存或本地內存)(進階配置)。 |
默認128M,不建議修改 |
任務堆外內存(Task Off-heap Memory) |
taskmanager.memory.task.off-heap.size |
用於 Flink 應用的算計及用戶代碼的堆外內存(直接內存或本地內存)。 |
默認是0 |
網絡內存(Network Memory) |
taskmanager.memory.network.min taskmanager.memory.network.max taskmanager.memory.network.fraction |
用於任務之間數據傳輸的直接內存(例如網絡傳輸緩衝)。該內存部分爲基於 Flink 總內存的受限的等比內存部分。 |
最小是64M 最大是1G 比例是0.1,最終計算出來的值會限制在64M~1G |
JVM Metaspace |
taskmanager.memory.jvm-metaspace.size |
Flink JVM 進程的 Metaspace。 |
默認256M |
JVM 開銷 |
taskmanager.memory.jvm-overhead.min taskmanager.memory.jvm-overhead.max taskmanager.memory.jvm-overhead.fraction |
用於其他 JVM 開銷的本地內存,例如棧空間、垃圾回收空間等。該內存部分爲基於進程總內存的受限的等比內存部分。 |
最小192M 最大1G 比例是0.1 |
網絡內存這部分和Flink反壓有關,後續有時間單獨開篇文章說一下,這一塊個人覺得還是蠻重要的。
用戶如何配置內存:
官網不建議同時設置進程總內存和 Flink 總內存。 這可能會造成內存配置衝突,從而導致部署失敗。 額外配置其他內存部分時,同樣需要注意可能產生的配置衝突。
所以Flink的內存配置是三選一:要麼配置進程總內存、要麼配置Flink總內存、要麼配置堆內內存+託管內存。個人覺得配置前兩者比較靠譜,除非對Flink內部原理特別瞭解,否則沒必要設置的那麼細。
怎麼判定TaskManager需要多少內存:
諮詢了下邊上對Flink比較瞭解的同事,Flink應用內存只要夠用就行了,配過多性能也不會再往上提升了,但是怎麼知道夠用呢?
Flink中的數據全部存在狀態中,即使是窗口的數據也存在窗口的State裏面(這裏面的數據不包括那些IO之間發來發去那些數據)。個人覺得可以這麼搞,看CheckPoint的大小大概可以估算出State狀態的大小,然後除以TaskManager的數量就大概可以知道每個TaskManager上保存的狀態的大小,這部分用的JVM Heap中的Task Heap的大小,然後根據那個比例推測下整個Flink程序應該設置的大小。
但CheckPoint的大小也得是在實際環境中跑起來觀察一下才能拿到。個人認爲可以這麼搞,拿家裏的10W條數據做個試驗,看下Checkpoint的大小,然後配置下內存。到現場之後,等比例進行一定的配置就可以了。
這樣就可以大概估計下初始值,然後進行微調,或者還有一種野路子,直接拿少量的數據配置個比較大的內存,然後再按照上面的方法計算...好像這樣還更加簡單,哈哈哈
參考:
https://ci.apache.org/projects/flink/flink-docs-release-1.10/zh/ops/memory/mem_setup.html
https://blog.csdn.net/nazeniwaresakini/article/details/105678146