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

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

前言

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

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

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

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

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

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

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

總而言之,測(cè)試驗(yàn)證了文章前面說(shuō)的對(duì)二進(jìn)制數(shù)據(jù)進(jìn)行操作的好處。

展望未來(lái)

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

總結(jié)

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

標(biāo)題名稱:深度解析 Flink 是如何管理好內(nèi)存的?
轉(zhuǎn)載來(lái)于:http://www.bm7419.com/news29/102479.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、云服務(wù)器、網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站設(shè)計(jì)ChatGPT、定制網(wǎng)站

廣告

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

營(yíng)銷型網(wǎng)站建設(shè)