Spark 記憶體分配

2021-09-02 20:30:12 字數 2972 閱讀 5583

這是spark1.5及以前堆記憶體分配圖

下邊對上圖進行更近一步的標註,紅線開始到結尾就是這部分的開始到結尾

spark 預設分配512mb jvm堆記憶體。出於安全考慮和避免記憶體溢位,spark只允許我們使用堆記憶體的90%,這在spark的spark.storage.safetyfraction 引數中配置著。也許你聽說的spark是乙個記憶體工具,spark允許你儲存資料在記憶體。其實,spark不是真正的記憶體工具,它只是允許你使用記憶體的lru(最近最少使用)快取 。所以,一部分記憶體要被用來快取你要處理的資料,這部分記憶體佔可用安全堆記憶體的60%,這個值在spark.storage.memoryfraction引數中配置。所以如果你想知道你可以存多少資料在spark中,spark.storage.safetyfraction 預設值為0.9,spark.storage.memoryfraction的預設值為0.6,

storage=總堆記憶體*0.9*0.6,所以你有54%的堆記憶體用來儲存資料。

shuffle記憶體:

spark.shuffle.safetyfraction * spark.shuffle.memoryfraction

spark.shuffle.safetyfraction預設為0.8或80%,spark.shuffle.memoryfraction預設為0.2或20%,則你最終可以使用0.8*0.2=0.16或16%的jvm 堆記憶體用於shuffle。

unroll記憶體:

spark允許資料以序列化或非序列化的形式儲存,序列化的資料不能拿過來直接使用,所以就需要先反序列化,即unroll。

heap size*spark.storage.safetyfraction*spark.storage.memoryfraction*spark.storage.unrollfraction=heap size *0.9*0.6*0.2=heap size * 0.108或10.8%的jvm 堆記憶體。

到此為止,你應該就知道spark是如何使用jvm記憶體的了,下邊是集群模式,以yarn為例,其它類似。

在yarn集群中,yarn resource manager管理集群的資源(實際就是記憶體)和一系列執行在集群node上yarn resource manager及集群nodes資源的使用。從yarn的角度,每乙個 node都代表了乙個可控制的記憶體資源,當你向yarn resource manager申請資源時,它會反饋給你哪個yarn node manager 可以連線並啟動乙個execution container給你。每乙個execution container都是乙個可以提供堆記憶體的jvm,jvm的位置是由yarn resource manager選擇的。

當你在yarn上啟動spark時,你可以指定executor的數量(–num-executors flag or spark.executor.instances parameter)、每個executor的記憶體大小(–executor-memory flag or spark.executor.memory  parameter)、每個executor的核心數量(–executor-cores flag of spark.executor.coresparameter)、每個task執行的核心數量(spark.task.cpusparameter),你也可以指定driver的記憶體大小(–driver-memory flag or spark.driver.memory parameter)。

當你在集群中執行某項任務時,乙個job會被切分成stages,每個stage會被分成多個task,每個task會被單獨分配,你可以把這些executor看成乙個個執行task的槽池(a pool of tasks execution slots)。如下看乙個例子:乙個集群有12個節點(yarn node manager),每個節點有64g記憶體、32核的cpu(16個物理核心,乙個物理核心可以虛擬成兩個)。每個節點你可以啟動兩個executors、每個executor分配26g記憶體(留一部分用於system process、yarn nm、datanode).所以集群一共可以處理 12 machines * 2 executors per machine * 12 cores per executor / 1 core for each task = 288 task slots。這意味著該集群可以並行執行288個task,充分利用集群的所有資源。你可以用來儲存資料的記憶體為= 0.9 spark.storage.safetyfraction * 0.6 spark.storage.memoryfraction * 12 machines * 2 executors per machine * 26 gb per executor = 336.96 gb。沒有那麼多,但是也足夠了。

到此,你已經知道spark如何分配 jvm記憶體,在集群中可以有多少個execution slots。那麼什麼是task,你可以把他想像成executor的某個執行緒,executor是乙個程序 ,它可以多執行緒的執行task.

下邊來解釋一下另乙個抽象概念"partition",你用來分析的所有資料都將被切分成partitions,那麼何為乙個partition,它又是由什麼決定的?partition的大小是由你使用的資料來源決定的,在spark中你可以使用的所有讀取資料的方式,大多你可以指定你的rdd中有多少個partitions。當你從hdfs中讀取乙個檔案時,hadoop的inputformat決定partition。通常由inputformat輸入的每乙個 split對應於rdd中的乙個partition,而每乙個split通常相當於hdfs中的乙個block(還有一些其它情況,暫不解釋,如text file壓縮後傳過一整個partition不能直接使用)。

乙個partition產生乙個task,並在資料所在的節點task slot執行(資料本地性)

Spark1 5堆記憶體分配

這是spark1.5堆記憶體分配圖 下邊對上圖進行更近一步的標註,紅線開始到結尾就是這部分的開始到結尾 spark 預設分配512mb jvm堆記憶體。出於安全考慮和避免記憶體溢位,spark只允許我們使用堆記憶體的90 這在spark的spark.storage.safetyfraction 引數...

spark動態資源分配

spark動態資源調整其實也就是說的executor數目支援動態增減,動態增減是根據spark應用的實際負載情況來決定。1.將spark.dynamicallocation.enabled設定為true。意思就是啟動動態資源功能 2.將spark.shuffle.service.enabled設定為...

記憶體分配 Go記憶體管理 記憶體分配一

go作為乙個比較新晚 新 的語言,自然借鑑前輩們的優點,比如說語言本身負責記憶體管理 對協程和高併發的高優支援 簡單高效的語法等。本篇及後續的幾篇要講的就是還沒提到的比較複雜的記憶體管理。學習記憶體管理 分配 前,如果有jvm的記憶體管理的基礎,會變得非常簡單,如果是第一次接觸記憶體管理,在看完go...