1. 程式人生 > >大資料IMF傳奇行動絕密課程第54課:Spark效能優化第十季之Spark統一記憶體管理

大資料IMF傳奇行動絕密課程第54課:Spark效能優化第十季之Spark統一記憶體管理

Spark效能優化第十季之Spark統一記憶體管理

1、傳統的Spark記憶體管理的問題
2、Spark統一記憶體管理
3、展望

Spark記憶體分為三部分:Execution、Sotrage、Other;
Shuffle,當記憶體不夠的時候下,磁碟IO很大負擔

10個Task並行,則會把記憶體分為10份,實際執行時Task可能會沾滿整個空間,其他任務分配不到空間。
即使一個Task不會把記憶體用完,另外一個Task申請記憶體,它有一個演算法,如果申請的記憶體不夠,Task不會自動Spill到disk,預設放一部分資料到記憶體中,有個百分比,這樣不斷重複,既消耗CPU又消耗記憶體。

這時就要Spill到磁碟

1、分散式系統的效能殺手是Shuffle,join、aggregation可能需要用很大記憶體,但是給他分配的很少,這不是有效的記憶體使用方法
2、假設需要Spill,計算時還要從磁碟讀到記憶體,這時磁碟IO是不能承受的
3、Storage空間不夠,計算結果丟失可能需要重新計算
4、假設Task佔滿記憶體,其他Cores都在空閒狀態
5、即使Spill資料到磁碟,它還是要申請一部分百分比的空間放一部分資料的

Execution分配記憶體:
ShuffleMemoryManager、TaskMemoryManager、ExecutorMemoryManager
最安全、廉價的STORAGE_LEVEL是MEMORY_AND_DISK_SER

Iterator一條一條讀取資料叫Unroll,無法一次性把所有的資料放進去,因為可能OOM。Unroll的記憶體空間是從Storage空間中獲得的,Unroll過程中會放盡量多的資料放入Storage中,Spark給了它一個引數,spark.storage.unroll.fraction預設也是0.2;unroll失敗的話則直接放到硬碟。

UnifiedMemoryManagement:
Execution Memory可以直接訪問Storage Memory,Storage Memory可以訪問Execution Memory,這兩個可以互相借記憶體。
預設兩部分加在一起為總堆大小-300MB,300MB可配置:spark.testing.reserveMemory RESERVED_SYSTEM_MOMORY_BYTES = 3 * 1024 * 1024是保留的記憶體大小。
spark.memory.storageFraction 預設為0.5,所以其最大空間為0.75 * 0.5 = 0.375倍的,且可以找execution memory借。如果借的還不夠的話,則有不同的處理方式
Storage可以向execution借記憶體,當execution需要記憶體時,則會將Storage的記憶體drop掉,知道足夠的空間夠自己使用。
相反execution也可以向Storage借記憶體,當Storage的Memory不夠的時候不會將Execution的記憶體drop掉,這是因為計算的時候牽扯很多東西,drop後太過於複雜。
圖54-1 Spark預設的記憶體分配方式