Spark性能優(yōu)化第十季之Spark統(tǒng)一內(nèi)存管理1、傳統(tǒng)的Spark內(nèi)存管理的問題 2、Spark統(tǒng)一內(nèi)存管理 3、展望 Spark內(nèi)存分為三部分:Execution、Sotrage、Other; Shuffle,當(dāng)內(nèi)存不夠的時候下,磁盤IO很大負(fù)擔(dān) 10個Task并行,則會把內(nèi)存分為10份,實(shí)際運(yùn)行時Task可能會沾滿整個空間,其他任務(wù)分配不到空間。 即使一個Task不會把內(nèi)存用完,另外一個Task申請內(nèi)存,它有一個算法,如果申請的內(nèi)存不夠,Task不會自動Spill到disk,默認(rèn)放一部分?jǐn)?shù)據(jù)到內(nèi)存中,有個百分比,這樣不斷重復(fù),既消耗CPU又消耗內(nèi)存。 這時就要Spill到磁盤 1、分布式系統(tǒng)的性能殺手是Shuffle,join、aggregation可能需要用很大內(nèi)存,但是給他分配的很少,這不是有效的內(nèi)存使用方法 2、假設(shè)需要Spill,計算時還要從磁盤讀到內(nèi)存,這時磁盤IO是不能承受的 3、Storage空間不夠,計算結(jié)果丟失可能需要重新計算 4、假設(shè)Task占滿內(nèi)存,其他Cores都在空閑狀態(tài) 5、即使Spill數(shù)據(jù)到磁盤,它還是要申請一部分百分比的空間放一部分?jǐn)?shù)據(jù)的 Execution分配內(nèi)存: ShuffleMemoryManager、TaskMemoryManager、ExecutorMemoryManager 最安全、廉價的STORAGE_LEVEL是MEMORY_AND_DISK_SER Iterator一條一條讀取數(shù)據(jù)叫Unroll,無法一次性把所有的數(shù)據(jù)放進(jìn)去,因?yàn)榭赡躉OM。Unroll的內(nèi)存空間是從Storage空間中獲得的,Unroll過程中會放盡量多的數(shù)據(jù)放入Storage中,Spark給了它一個參數(shù),spark.storage.unroll.fraction默認(rèn)也是0.2;unroll失敗的話則直接放到硬盤。 UnifiedMemoryManagement: Execution Memory可以直接訪問Storage Memory,Storage Memory可以訪問Execution Memory,這兩個可以互相借內(nèi)存。 默認(rèn)兩部分加在一起為總堆大小-300MB,300MB可配置:spark.testing.reserveMemory RESERVED_SYSTEM_MOMORY_BYTES = 3 * 1024 * 1024是保留的內(nèi)存大小。 spark.memory.storageFraction 默認(rèn)為0.5,所以其最大空間為0.75 * 0.5 = 0.375倍的,且可以找execution memory借。如果借的還不夠的話,則有不同的處理方式 Storage可以向execution借內(nèi)存,當(dāng)execution需要內(nèi)存時,則會將Storage的內(nèi)存drop掉,知道足夠的空間夠自己使用。 相反execution也可以向Storage借內(nèi)存,當(dāng)Storage的Memory不夠的時候不會將Execution的內(nèi)存drop掉,這是因?yàn)橛嬎愕臅r候牽扯很多東西,drop后太過于復(fù)雜。

|