Apache Flink 1.10 TaskManager 內存管理優化

點擊上方“zhisheng”,選擇“設爲星標”

後臺回覆"666",獲取最新資料

Apache Flink 1.10 對 TaskManager 的內存模型和 Flink 應用程序的配置選項進行了重大變更。這些最近引入的更改做到了對內存消耗提供了嚴格的控制,使得 Flink 在各種部署環境(例如 Kubernetes,Yarn,Mesos)更具有適應能力,

在本文中,我們將介紹 Flink 1.10 中的內存模型、如何設置和管理 Flink 應用程序的內存消耗以及社區在最新的 Apache Flink Release 版本中的變化。

Flink 內存模型的介紹

對 Apache Flink 的內存模型有清晰的瞭解,可以使您更有效地管理各種情況下的資源使用情況。下圖描述了 Flink 中的主要內存組件:

Flink: Total Process Memory

TaskManager 進程是一個 JVM 進程,從較高的角度來看,它的內存由 JVM Heap 和 Off-Heap 組成。這些類型的內存由 Flink 直接使用,或由 JVM 用於其特定目的(比如元空間 metaspace)。

Flink 中有兩個主要的內存使用者:

用戶代碼中的作業 task 算子Flink 框架本身的內部數據結構、網絡緩衝區 (Network Buffers)等

請注意,用戶代碼可以直接訪問所有的內存類型:JVM 堆、Direct 和 Native 內存。因此,Flink 不能真正控制其分配和使用。但是,有兩種供作業 Task 使用並由 Flink 嚴格控制的 Off-Heap 內存,它們分別是:

Managed Memory (Off-Heap)網絡緩衝區 (Network Buffers)

網絡緩衝區 (Network Buffers) 是 JVM Direct 內存的一部分,分配在算子和算子之間用於進行用戶數據的交換。

怎麼去配置 Flink 的內存

在最新 Flink 1.10 版本中,爲了提供更好的用戶體驗,框架提供了內存組件的高級和細粒度調優。在 TaskManager 中設置內存基本上有三種選擇。

前兩個(也是最簡單的)選擇是需要你配置以下兩個選項之一,以供 TaskManager 的 JVM 進程使用的總內存:

Total Process Memory:Flink Java 應用程序(包括用戶代碼)和 JVM 運行整個進程所消耗的總內存。Total Flink Memory:僅 Flink Java 應用程序消耗的內存,包括用戶代碼,但不包括 JVM 爲其運行而分配的內存。

如果是以 standalone 模式部署,則建議配置 Total Flink Memory,在這種情況下,顯式聲明爲 Flink 分配多少內存是一種常見的做法,而外部 JVM 開銷卻很少。

對於在容器化環境(例如 Kubernetes,Yarn 或 Mesos)中部署 Flink 的情況,建議配置 Total Process Memory,因爲它表示所請求容器的總內存大小,容器化環境通常嚴格執行此內存限制。

其餘的內存組件將根據其默認值或其他已配置的參數自動進行調整。Flink 還會檢查整體一致性。你可以在相應的文檔中找到有關不同內存組件的更多信息。此外,你可以使用 FLIP-49 的配置電子表格嘗試不同的配置選項,並根據你的情況檢查相應的結果。

如果要從 1.10 之前的 Flink 版本進行遷移,我們建議你遵循 Flink 文檔的遷移指南中的步驟。

其他組件

在配置 Flink 的內存時,可以使用相應選項的值固定不同內存組件的大小,也可以使用多個選項進行調整。下面我們提供有關內存設置的更多信息。

按比例細分 Total Flink Memory

此方法允許按比例細分 Total Flink Memory,其中 Managed Memory(如果未明確設置)和網絡緩衝區可以佔用一部分。然後,將剩餘的內存分配給 Task Heap(如果未明確設置)和其他固定的 JVM Heap 和 Off-Heap 組件。下圖是這種設置的示例:

請注意

Flink 會校驗分配的 Network Memory 大小在其最小值和最大值之間,否則 Flink 的啓動會失敗,最大值和最小值的限制具有默認值,這些默認值是可以被相應的配置選項覆蓋。

通常,Flink 將配置的佔比分數視爲提示。在某些情況下,真正分配的值可能與佔比分數不匹配。例如,如果將 Total Flink Memory 和 Task Heap 配置爲固定值,則 Managed Memory 將獲得一定比例的內存,而 Network Memory 將獲得可能與該比例不完全匹配的剩餘內存。

控制容器內存限制的更多提示

堆內存和 direct 內存的使用是由 JVM 管理的。在 Apache Flink 或其用戶應用程序中,還有許多其他 native 內存消耗的可能來源,它們不是由 Flink 或 JVM 管理的。通常很難控制它們的限制大小,這會使調試潛在的內存泄漏變得複雜。

如果 Flink 的進程以不受管理的方式分配了過多的內存,則在容器化環境中通常可能導致 TaskManager 容器會被殺死。在這種情況下,可能很難理解哪種類型的內存消耗已超過其限制。Flink 1.10 引入了一些特定的調整選項,以清楚地表示這些組件。儘管 Flink 不能始終嚴格執行嚴格的限制和界限,但此處的想法是明確計劃內存使用情況。下面我們提供一些示例,說明內存設置如何防止容器超出其內存限制:

RocksDB 狀態不能太大:RocksDB 狀態後端的內存消耗是在 Managed Memory 中解決的。RocksDB 默認情況下遵守其限制(僅自 Flink 1.10 起)。你可以增加 Managed Memory 的大小以提高 RocksDB 的性能,也可以減小 Managed Memory 的大小以節省資源。用戶代碼或其依賴項會消耗大量的 off-heap 內存:調整 Task Off-Heap 選項可以爲用戶代碼或其任何依賴項分配額外的 direct 或 native 內存。Flink 無法控制 native 分配,但它設置了 JVM Direct 內存分配的限制。Direct 內存限制由 JVM 強制執行。JVM metaspace 需要額外的內存:如果遇到 OutOfMemoryError:Metaspace,Flink 提供了一個增加其限制的選項,並且 JVM 將確保不超過該限制。JVM 需要更多內部內存:無法直接控制某些類型的 JVM 進程分配,但是 Flink 提供了 JVM 開銷選項。這些選項允許聲明額外的內存量,這些內存是爲這些分配所預期的,並且未被其他選項覆蓋。

結論

最新的 Flink 版本(Flink 1.10)對 Flink 的內存配置進行了一些重大更改,從而可以比以前更好地管理應用程序內存和調試 Flink。未來 JobManager 的內存模型也會採取類似的更改,可以參考 FLIP-116,因此請繼續關注即將發佈的新版本中新增的功能。如果你對社區有任何建議或問題,我們建議你註冊 Apache Flink 郵件列表並參與其中的討論。

博客英文地址:https://flink.apache.org/news/2020/04/21/memory-management-improvements-flink-1.10.html
作者: Andrey Zagrebin
本文翻譯作者:zhisheng
翻譯後首發地址:http://www.54tianzhisheng.cn/2020/05/16/flink-taskmanager-memory-model/




基於 Apache Flink 的實時監控告警系統
日誌收集Agent,陰暗潮溼的地底世界
2020 繼續踏踏實實的做好自己

END
關注我
公衆號(zhisheng)裏回覆 面經、ES、Flink、 Spring、Java、Kafka、監控 等關鍵字可以查看更多關鍵字對應的文章。你點的每個贊,我都認真當成了喜歡
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章