Apache Flink 通過嚴(yán)格控制其各個(gè)組件的內(nèi)存使用,在 JVM 之上提供了高效的工作負(fù)載。雖然社區(qū)努力為所有配置提供合理的默認(rèn)值,但不可能適用于用戶在 Flink 上部署的所有應(yīng)用程序。為了向我們的用戶提供最大的生產(chǎn)價(jià)值,F(xiàn)link 允許在集群內(nèi)進(jìn)行高級和細(xì)粒度的內(nèi)存分配調(diào)優(yōu)。
我們都知道不管 Flink 運(yùn)行在什么集群上,真正干活的都是 TaskManager (后面簡稱為 TM),JobManager (后面簡稱為 JM)只負(fù)責(zé)任務(wù)的調(diào)度,所以了解 TM 的內(nèi)存模型是非常有必要的,今天這篇文章就來說一下 TM 的內(nèi)存模型,JM 的內(nèi)存模型相對簡單,這里就不再說了.
在 Flink 1.10.0 版本中,社區(qū)對 TM 的內(nèi)存模型做了進(jìn)一步的改進(jìn)和升級,雖然內(nèi)存的劃分已經(jīng)很明確,但還是讓人看的眼花繚亂,容易混淆.先來看下面這張圖.
Flink TM 內(nèi)存模型

在 Flink 1.12.0 版本中對 UI 進(jìn)行了改進(jìn),在 TM 的頁面增加了一個(gè)內(nèi)存模型圖,清楚的顯示了每個(gè)區(qū)域的內(nèi)存配置以及使用情況.
★
Total Process Memory (進(jìn)程總內(nèi)存) 包含了 Flink 應(yīng)用程序使用的全部內(nèi)存資源:Total Flink Memory (Flink應(yīng)用使用的內(nèi)存) + 運(yùn)行 Flink JVM 使用的內(nèi)存。Total Process Memory 對應(yīng) Yarn/Mesos 等容器化部署模式(需要用戶指定),相當(dāng)于申請容器的大小,Total Flink Memory 對應(yīng) standalone 部署模式(需要用戶指定)。
Total Flink Memory 內(nèi)部分成了:堆內(nèi)內(nèi)存 + 堆外內(nèi)存:
堆內(nèi)內(nèi)存包括兩部分:FreameWork Heap Memory (框架堆內(nèi)存) + Task Heap Memory (任務(wù)堆內(nèi)存)
堆外內(nèi)存包含三部分:Managed Memory (托管內(nèi)存) + Framework Off-heap Memory (框架堆外內(nèi)存) + Network Memory (網(wǎng)絡(luò)內(nèi)存)
”
下面就按照上圖中編號順序分別介紹一下這些內(nèi)存的作用以及如何配置
Framework Heap
含義描述
Flink 框架本身占用的內(nèi)存,這部分的內(nèi)存一般情況下是不需要修改的,在特殊的情況下可能需要調(diào)整.
參數(shù)設(shè)置
taskmanager.memory.framework.heap.size:堆內(nèi)部分(Framework Heap),默認(rèn)值 128M;
taskmanager.memory.framework.off-heap.size:堆外部分(Framework Off-Heap),以直接內(nèi)存形式分配,默認(rèn)值 128M。
Task Heap
含義描述
用于 Flink 應(yīng)用的算子及用戶代碼占用的內(nèi)存。
參數(shù)設(shè)置
- taskmanager.memory.task.heap.size:堆內(nèi)部分(Task Heap),無默認(rèn)值,一般不建議設(shè)置,會自動(dòng)用 Flink 總內(nèi)存減去框架、托管、網(wǎng)絡(luò)三部分的內(nèi)存推算得出。
- taskmanager.memory.task.off-heap.size:堆外部分(Task Off-Heap),以直接內(nèi)存形式分配,默認(rèn)值為 0,即不使用。如果代碼中需要調(diào)用 Native Method 并分配堆外內(nèi)存,可以指定該參數(shù)。一般不使用,所以大多數(shù)時(shí)候可以保持0。
Managed Memory
含義描述
純堆外內(nèi)存,由 MemoryManager 管理,用于中間結(jié)果緩存、排序、哈希表等,以及 RocksDB 狀態(tài)后端??梢姡琑ocksDB 消耗的內(nèi)存可以由用戶顯式控制了,不再像舊版本一樣難以預(yù)測和調(diào)節(jié)。
參數(shù)設(shè)置
- taskmanager.memory.managed.fraction:托管內(nèi)存占 Flink 總內(nèi)存 taskmanager.memory.flink.size 的比例,默認(rèn)值 0.4;
- taskmanager.memory.managed.size:托管內(nèi)存的大小,無默認(rèn)值,一般也不指定,而是依照上述比例來推定,更加靈活。
Network
含義描述
Network Memory 使用的是 Directory memory,在 Task 與 Task 之間進(jìn)行數(shù)據(jù)交換時(shí)(shuffle),需要將數(shù)據(jù)緩存下來,緩存能夠使用的內(nèi)存大小就是這個(gè) Network Memory。它由是三個(gè)參數(shù)決定:
參數(shù)設(shè)置
- taskmanager.memory.network.min:網(wǎng)絡(luò)緩存的最小值,默認(rèn) 64MB;
- taskmanager.memory.network.max:網(wǎng)絡(luò)緩存的最大值,默認(rèn) 1GB;
- taskmanager.memory.network.fraction:網(wǎng)絡(luò)緩存占 Flink 總內(nèi)存 taskmanager.memory.flink.size 的比例,默認(rèn)值 0.1。若根據(jù)此比例算出的內(nèi)存量比最小值小或比最大值大,就會限制到最小值或者最大值。
JVM Metaspace
含義描述
從 JDK 8 開始,JVM 把永久代拿掉了。類的一些元數(shù)據(jù)放在叫做 Metaspace 的 Native Memory 中。在 Flink 中的 JVM Metaspace Memory 也一樣,它配置的是 Task Manager JVM 的元空間內(nèi)存大小。
參數(shù)設(shè)置
- taskmanager.memory.jvm-metaspace.size:默認(rèn)值 256MB。
JVM Overhead
含義描述
保留給 JVM 其他的內(nèi)存開銷。例如:Thread Stack、code cache、GC 回收空間等等。和 Network Memory 的配置方法類似。它也由三個(gè)配置決定
參數(shù)設(shè)置
- taskmanager.memory.jvm-overhead.min:JVM 額外開銷的最小值,默認(rèn) 192MB;
- taskmanager.memory.jvm-overhead.max:JVM 額外開銷的最大值,默認(rèn) 1GB;
- taskmanager.memory.jvm-overhead.fraction:JVM 額外開銷占 TM 進(jìn)程總內(nèi)存
- taskmanager.memory.process.size(注意不是 Flink 總內(nèi)存)的比例,默認(rèn)值 0.1。若根據(jù)此比例算出的內(nèi)存量比最小值小或比最大值大,就會限制到最小值或者最大值。
我們再來看一下 TM 啟動(dòng)日志里面內(nèi)存相關(guān)的配置信息如下:
<pre class="custom" data-tool="mdnice編輯器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - Program Arguments: INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - -D INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - taskmanager.memory.framework.off-heap.size=134217728b(128M) INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - -D INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - taskmanager.memory.network.max=214748368b(204.8M) INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - -D INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - taskmanager.memory.network.min=214748368b(204.8M) INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - -D INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - taskmanager.memory.framework.heap.size=134217728b(128M) INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - -D INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - taskmanager.memory.managed.size=858993472b(819.2M) INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - -D INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - taskmanager.cpu.cores=4.0 INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - -D INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - taskmanager.memory.task.heap.size=805306352b(767.9M) INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - -D INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - taskmanager.memory.task.off-heap.size=0b </pre>
這個(gè)內(nèi)存就是上圖中 Configured Values 顯示的值,我們把這些值加起來 taskmanager.memory.framework.off-heap.size + taskmanager.memory.network.max + taskmanager.memory.framework.heap.size + taskmanager.memory.managed.size + taskmanager.memory.task.heap.size = 128 + 205 + 128 + 819 + 768 = taskmanager.memory.flink.size = 2048M 這個(gè)結(jié)果跟我們在 flink-conf.yaml 中的配置是能對上的.
總結(jié)
上面這么多的內(nèi)存,到底應(yīng)該怎么配置呢?首先官網(wǎng)不建議同時(shí)設(shè)置進(jìn)程總內(nèi)存和 Flink 總內(nèi)存。 這可能會造成內(nèi)存配置沖突,從而導(dǎo)致部署失敗。 額外配置其他內(nèi)存部分時(shí),同樣需要注意可能產(chǎn)生的配置沖突。
其實(shí) taskmanager.memory.framework.heap.size ,taskmanager.memory.framework.off-heap.size,JVM Metaspace,JVM Overhead 這幾個(gè)參數(shù)一般情況下是不需要配置的,走默認(rèn)值就可以了.我們主要關(guān)注的是 Task Heap、Managed Memory、Network 這幾部分的內(nèi)存,當(dāng)然 Flink 本身也會計(jì)算出這 3 部分的內(nèi)存,我們自己也需要根據(jù)任務(wù)的特點(diǎn),比如流量大小,狀態(tài)大小等去調(diào)整.
推薦閱讀
★
Flink SQL 如何實(shí)現(xiàn)列轉(zhuǎn)行?
Flink SQL 結(jié)合 HiveCatalog 使用
Flink SQL 解析嵌套的 JSON 數(shù)據(jù)
Flink SQL 中動(dòng)態(tài)修改 DDL 的屬性
Flink 1.11.x WatermarkStrategy 不兼容問題
”
[圖片上傳失敗...(image-6a4c29-1617465251937)]
如果你覺得文章對你有幫助,麻煩點(diǎn)一下贊和在看吧,你的支持是我創(chuàng)作的最大動(dòng)力.