深度解析 Flink 是如何管理好內(nèi)存的?

2021-02-23    分類: 網(wǎng)站建設(shè)

前言

如今,許多用于分析大型數(shù)據(jù)集的開源系統(tǒng)都是用 Java 或者是基于 JVM 的編程語言實現(xiàn)的。最著名的例子是 Apache Hadoop,還有較新的框架,如 Apache Spark、Apache Drill、Apache Flink。基于 JVM 的數(shù)據(jù)分析引擎面臨的一個常見挑戰(zhàn)就是如何在內(nèi)存中存儲大量的數(shù)據(jù)(包括緩存和高效處理)。合理的管理好 JVM 內(nèi)存可以將 難以配置且不可預(yù)測的系統(tǒng) 與 少量配置且穩(wěn)定運行的系統(tǒng)區(qū)分開來。

在這篇文章中,我們將討論 Apache Flink 如何管理內(nèi)存,討論其自定義序列化與反序列化機制,以及它是如何操作二進制數(shù)據(jù)的。

數(shù)據(jù)對象直接放在堆內(nèi)存中

在 JVM 中處理大量數(shù)據(jù)最直接的方式就是將這些數(shù)據(jù)做為對象存儲在堆內(nèi)存中,然后直接在內(nèi)存中操作這些數(shù)據(jù),如果想進行排序則就是對對象列表進行排序。然而這種方法有一些明顯的缺點,首先,在頻繁的創(chuàng)建和銷毀大量對象的時候,監(jiān)視和控制堆內(nèi)存的使用并不是一件很簡單的事情。如果對象分配過多的話,那么會導(dǎo)致內(nèi)存過度使用,從而觸發(fā) OutOfMemoryError,導(dǎo)致 JVM 進程直接被殺死。另一個方面就是因為這些對象大都是生存在新生代,當 JVM 進行垃圾回收時,垃圾收集的開銷很容易達到 50% 甚至更多。最后就是 Java 對象具有一定的

測試是在 8 核機器上運行單線程,因此一個核心的完全利用僅對應(yīng) 12.5% 的總體利用率。截圖顯示,對二進制數(shù)據(jù)進行操作可顯著減少垃圾回收活動。對于對象存在堆中,垃圾收集器在排序緩沖區(qū)被填滿時以非常短的時間間隔運行,并且即使對于單個處理線程也會導(dǎo)致大量 CPU 使用(排序本身不會觸發(fā)垃圾收集器)。JVM 垃圾收集多個并行線程,解釋了高CPU 總體利用率。另一方面,對序列化數(shù)據(jù)進行操作的方法很少觸發(fā)垃圾收集器并且 CPU 利用率低得多。實際上,如果使用 Flink 序列化的方式在 Integer 字段上對 Tuple 進行排序,則垃圾收集器根本不運行,因為對于成對比較,不需要反序列化任何對象。Kryo 序列化需要比較多的垃圾收集,因為它不使用二進制排序 key 并且每次排序都要反序列化兩個對象。

內(nèi)存使用情況上圖顯示 Flink 序列化和 Kryo 序列化不斷的占用大量內(nèi)存

存使用情況圖表顯示flink-serialized和kryo-serialized不斷占用大量內(nèi)存。這是由于 MemorySegments 的預(yù)分配。實際內(nèi)存使用率要低得多,因為排序緩沖區(qū)并未完全填充。下表顯示了每種方法的內(nèi)存消耗。1000 萬條數(shù)據(jù)產(chǎn)生大約 280 MB 的二進制數(shù)據(jù)(對象數(shù)據(jù)、指針和排序 key),具體取決于使用的序列化程序以及二進制排序 key 的存在和大小。將其與數(shù)據(jù)存儲在堆上的方法進行比較,我們發(fā)現(xiàn)對二進制數(shù)據(jù)進行操作可以顯著提高內(nèi)存效率。在我們的基準測試中,如果序列化為排序緩沖區(qū)而不是將其作為堆上的對象保存,則可以在內(nèi)存中對兩倍以上的數(shù)據(jù)進行排序。

總而言之,測試驗證了文章前面說的對二進制數(shù)據(jù)進行操作的好處。

展望未來

Apache Flink 具有相當多的高級技術(shù),可以通過有限的內(nèi)存資源安全有效地處理大量數(shù)據(jù)。但是有幾點可以使 Flink 更有效率。Flink 社區(qū)正在努力將管理內(nèi)存移動到堆外內(nèi)存。這將允許更小的 JVM,更低的垃圾收集開銷,以及更容易的系統(tǒng)配置。使用 Flink 的 Table API,所有操作(如 aggregation 和 projection)的語義都是已知的(與黑盒用戶定義的函數(shù)相反)。因此,我們可以為直接對二進制數(shù)據(jù)進行操作的 Table API 操作生成代碼。進一步的改進包括序列化設(shè)計,這些設(shè)計針對應(yīng)用于二進制數(shù)據(jù)的操作和針對序列化器和比較器的代碼生成而定制。

總結(jié)

  • Flink 的主動內(nèi)存管理減少了因觸發(fā) OutOfMemoryErrors 而殺死 JVM 進程和垃圾收集開銷的問題。
  • Flink 具有高效的數(shù)據(jù)序列化和反序列化機制,有助于對二進制數(shù)據(jù)進行操作,并使更多數(shù)據(jù)適合內(nèi)存。
  • Flink 的 DBMS 風格的運算符本身在二進制數(shù)據(jù)上運行,在必要時可以在內(nèi)存中高性能地傳輸?shù)酱疟P。

文章題目:深度解析 Flink 是如何管理好內(nèi)存的?
瀏覽地址:http://bm7419.com/news/102479.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗、云服務(wù)器商城網(wǎng)站、網(wǎng)站設(shè)計動態(tài)網(wǎng)站、企業(yè)網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)