Spark到底怎么確認內(nèi)存夠不夠用的?超大超詳細圖解!讓你掌握Spark memeoryStore內(nèi)存管理的精髓

      網(wǎng)友投稿 1193 2022-05-28

      首先回顧一下spark中的BlockManager和memoryStore是做什么的。

      具體可以看這篇文章:

      spark的內(nèi)存管理機制學(xué)習(xí)——BlockManager

      他主要是將沒有序列化的java對象數(shù)組或者序列化的byteBuffer放到內(nèi)存中。

      但是這就涉及到一些內(nèi)存管理的問題,如果放不下,是不是要放磁盤?什么時候認為放不下?這里會一一解讀。

      MemoryStore的putIterator

      這個方法是把一堆values的數(shù)組內(nèi)容放入內(nèi)存中(本質(zhì)上就是放到Map中。

      如果發(fā)現(xiàn)內(nèi)存足夠,能夠申請,則調(diào)用putArray把數(shù)據(jù)寫入內(nèi)存(就是放到map中), 否則就去調(diào)用diskStore的接口寫入磁盤中。

      這里我先打住,不直接往下講,而是給自己假設(shè)場景,如果是自己在開發(fā)計算引擎,寫executor里的block緩存,肯定需要思考這個問題:

      什么時候認為內(nèi)存是足夠的?

      最簡單的一個做法:

      我給每個memoryStore設(shè)定一個閾值MaxMemory,

      維護一個值currentMemory, 這個值就是memoryStroe里那個Map所占的大小。

      然后遍歷計算一下輸入?yún)?shù)values所占的內(nèi)存大小 needMemory

      如果needMemory > maxMemory - currentMemory, 則認為內(nèi)存不足,寫入到磁盤。

      這個做法相當(dāng)于直接把整個values大小都計算好之后,如果ok,馬上進行寫入內(nèi)存操作。

      如果是memoryStore是單線程的模塊那ok, 但如果這個putIterator是一個支持多線程寫入的模塊呢?

      當(dāng)我覺得100M足夠,我寫入,可能得花10s, 然后另外一個線程也覺得100M足夠,也要寫入,結(jié)果寫到一半發(fā)現(xiàn)內(nèi)存不夠,就尷尬了。

      因此問題變?yōu)椋?/p>

      多線程時,如果確保計算的內(nèi)存量是有效的?

      一種方式,就是每次確定要寫入時, 把要寫入的這100M的量直接加到currentMemory中。 ?后面的線程要判斷時,直接拿最新的curentMemory判斷。

      但實際上這個數(shù)據(jù)并沒有真正寫入map中, 有可能中間出現(xiàn)寫入失敗或者線程中斷, 那這時候已經(jīng)被處理過的currentMemory就不好搞了。

      所以引入一個概念,叫展開內(nèi)存unrollMemory。

      每個線程都有自己的unrollMemory, 可以理解為該線程 準(zhǔn)備 寫入到內(nèi)存中的大小。

      因此我們統(tǒng)計剩余可寫入內(nèi)存時, 實際上是等于 MaxMemory - currentMemory - 所有線程unrollMemory總和。

      但是我們又不能讓線程展開的這個值正好把剩余內(nèi)存占滿,所以會設(shè)定一個展開內(nèi)存總和maxUnrollMemory,替代MaxMemory。

      因此此時我這個線程可用的剩余內(nèi)存space,實際上為

      maxUnrollMemory - ?cyrrentUnrollMemory。

      但問題又來了,如果我們假想的可分配內(nèi)存比實際剩余內(nèi)存小,怎么辦?如下圖:

      一種方式,是發(fā)現(xiàn)假想剩余內(nèi)存小于實際剩余內(nèi)存時,認為內(nèi)存不足,把數(shù)據(jù)寫入磁盤。

      但有個問題, 假設(shè)我需要寫入100M, 實際剩余內(nèi)存是98M, 其實只差了2M, 那為什么不能擠擠呢?只差2M了!

      然而我肯定不能去動其他線程的unrollMemory,畢竟人家都認為自己是ok的準(zhǔn)備寫入了,你總不能插隊吧?如果能動其他線程準(zhǔn)備寫入的數(shù)據(jù),這管理就太復(fù)雜了。

      因此我們需要去已使用內(nèi)存MemoryEntry里面找, 找一下是不是有比較小的block塊,比如有一個塊只有5M, 那我就把這個block塊放入磁盤,那么我就可以塞進去了!

      解答完上述問題后,再學(xué)習(xí)memoryStore的內(nèi)存寫入管理機制,就容易多了。

      memoryStore完整安全展開流程

      這里的計算不同于上文中提到的直接遍歷完之后判斷總大小

      因為當(dāng)時傳入的是一個迭代器,只能迭代一次,每次迭代時都需要放入vector這個臨時存儲的列表中,萬一超級大,放入vector時超出范圍就GG了, 所以它實際時每隔一段就會檢查一下是否超出閾值。

      spark到底是怎么確認內(nèi)存夠不夠用的?超大超詳細圖解!讓你掌握Spark memeoryStore內(nèi)存管理的精髓

      2. 計算剩余可用的展開空間

      下圖標(biāo)注的地方就是上文最后算出的space:

      如果小于實際內(nèi)存,那么就需要去已分配的內(nèi)存中找,看下能不能選一些小朋友去磁盤中。

      spark不足時,檢查能否抽一些已分配內(nèi)存區(qū)磁盤

      核心方法來自ensureFreeSpace

      我們看下它的實現(xiàn):

      這個過程比較簡單,也沒做太多優(yōu)化,不考慮最優(yōu)情況,否則會有排序的性能問題。

      如果發(fā)現(xiàn)抽內(nèi)存也不夠用, 那就直接認為不行了。

      如果ok,那就認為可行,

      內(nèi)存足夠分配,寫入

      最后會返回一個vector數(shù)據(jù)

      這個vector會拿去做真正的寫入操作。

      完整高清大圖過程:

      EI企業(yè)智能 可信智能計算服務(wù) TICS 大數(shù)據(jù) 智能數(shù)據(jù)

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:【實施工程師】ubuntu創(chuàng)建文件【實施工程師】ubuntu創(chuàng)建文件
      下一篇:Kafka生產(chǎn)發(fā)送數(shù)據(jù)失敗
      相關(guān)文章
      中文字幕在线观看亚洲视频| 久久久久久久亚洲精品| 亚洲最大激情中文字幕| 色五月五月丁香亚洲综合网| 亚洲色偷偷偷综合网| 在线观看日本亚洲一区| 亚洲制服丝袜精品久久| 亚洲精品美女在线观看播放| 亚洲视频免费一区| 18亚洲男同志videos网站| 4480yy私人影院亚洲| 亚洲综合网美国十次| 亚洲国产高清在线精品一区| 亚洲国产精品综合久久2007| 亚洲伊人久久大香线焦| 久久亚洲国产最新网站| 亚洲熟女综合一区二区三区| 亚洲国产精品无码观看久久| 亚洲Av无码国产一区二区| 处破女第一次亚洲18分钟| 亚洲国产精品一区二区第一页免| 亚洲国产精品成人网址天堂| 亚洲中文字幕无码爆乳av中文 | 亚洲国产精品yw在线观看| 91亚洲国产成人久久精品网址| 亚洲中文字幕久久精品无码2021| 亚洲国产精品日韩在线| 亚洲国产成人91精品| 亚洲一区二区三区成人网站 | 亚洲AV无码一区二区乱子伦| 亚洲无线电影官网| 亚洲成人免费网址| 日韩亚洲国产高清免费视频| 亚洲va中文字幕| 亚洲伊人成无码综合网| 亚洲AV无码乱码在线观看裸奔| 亚洲精品日韩专区silk| 亚洲国产乱码最新视频| 国产精品亚洲а∨天堂2021 | 中文字幕日韩亚洲| 亚洲av丰满熟妇在线播放|