57、Spark性能優(yōu)化之?dāng)?shù)據(jù)本地化

數(shù)據(jù)本地化背景

數(shù)據(jù)本地化對(duì)于Spark Job性能有著巨大的影響。如果數(shù)據(jù)以及要計(jì)算它的代碼是在一起的,那么性能當(dāng)然會(huì)非常高。但是,如果數(shù)據(jù)和計(jì)算它的代碼是分開的,那么其中之一必須到另外一方的機(jī)器上。通常來說,移動(dòng)代碼到其他節(jié)點(diǎn),會(huì)比移動(dòng)數(shù)據(jù)到代碼所在的節(jié)點(diǎn)上去,速度要快得多,因?yàn)榇a比較小。Spark也正是基于這個(gè)數(shù)據(jù)本地化的原則來構(gòu)建task調(diào)度算法的。
數(shù)據(jù)本地化,指的是,數(shù)據(jù)離計(jì)算它的代碼有多近?;跀?shù)據(jù)距離代碼的距離,有幾種數(shù)據(jù)本地化級(jí)別:

  1. PROCESS_LOCAL:數(shù)據(jù)和計(jì)算它的代碼在同一個(gè)JVM進(jìn)程中。
  2. NODE_LOCAL:數(shù)據(jù)和計(jì)算它的代碼在一個(gè)節(jié)點(diǎn)上,但是不在一個(gè)進(jìn)程中,比如在不同的executor進(jìn)程中,或者是數(shù)據(jù)在HDFS文件的block中。
  3. NO_PREF:數(shù)據(jù)從哪里過來,性能都是一樣的。
  4. RACK_LOCAL:數(shù)據(jù)和計(jì)算它的代碼在一個(gè)機(jī)架上。
  5. ANY:數(shù)據(jù)可能在任意地方,比如其他網(wǎng)絡(luò)環(huán)境內(nèi),或者其他機(jī)架上。

原理

數(shù)據(jù)本地化原理.png

Task要處理的partition的數(shù)據(jù),在某一個(gè)Executor中,TaskScheduler首先會(huì)盡量用最好的本地化級(jí)別去啟動(dòng)task,也就是說,會(huì)盡量在哪個(gè)包含了要處理的partition的executor中,去啟動(dòng)task
此時(shí),Executor已經(jīng)再執(zhí)行好幾個(gè)task了,沒有空閑資源來執(zhí)行這個(gè)task
默認(rèn)情況下,spark會(huì)等待一會(huì),等待Executor什么時(shí)候可以空閑出一個(gè)cpu core,從而來啟動(dòng)這個(gè)task,讓它實(shí)現(xiàn)最好的本地化級(jí)別
但是如果等待了一會(huì)(時(shí)間是可以調(diào)優(yōu)的,通過參數(shù)設(shè)置),發(fā)現(xiàn)始終沒有等到Executor的core釋放,那么會(huì)放大一個(gè)級(jí)別,去嘗試啟動(dòng)這個(gè)task
如果這個(gè)rdd之前持久化過,task會(huì)去調(diào)用RDD的iterator()方法,然后通過executor關(guān)聯(lián)的BlockManager,來嘗試獲取數(shù)據(jù),BlockManager底層,首先嘗試從getLocal()在本地找數(shù)據(jù),如果沒有找到的話,那么用getRemote(),通過BlockTransferService,鏈接到有數(shù)據(jù)的BlockManager,來獲取數(shù)據(jù)
如果沒有持久化過,那么就computerOrReadCheckpoint()
如果還是不能啟動(dòng),繼續(xù)放大級(jí)別

數(shù)據(jù)本地化優(yōu)化

Spark傾向于使用最好的本地化級(jí)別來調(diào)度task,但是這是不可能的。如果沒有任何未處理的數(shù)據(jù)在空閑的executor上,那么Spark就會(huì)放低本地化級(jí)別。這時(shí)有兩個(gè)選擇:第一,等待,直到executor上的cpu釋放出來,那么就分配task過去;第二,立即在任意一個(gè)executor上啟動(dòng)一個(gè)task。
Spark默認(rèn)會(huì)等待一會(huì)兒,來期望task要處理的數(shù)據(jù)所在的節(jié)點(diǎn)上的executor空閑出一個(gè)cpu,從而將task分配過去。只要超過了時(shí)間,那么Spark就會(huì)將task分配到其他任意一個(gè)空閑的executor上。
可以設(shè)置參數(shù),spark.locality系列參數(shù),來調(diào)節(jié)Spark等待task可以進(jìn)行數(shù)據(jù)本地化的時(shí)間。spark.locality.wait(3000毫秒)、spark.locality.wait.node、spark.locality.wait.process、spark.locality.wait.rack。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.1、 分配更多資源 1.1.1、分配哪些資源? Executor的數(shù)量 每個(gè)Executor所能分配的CPU數(shù)...
    miss幸運(yùn)閱讀 3,283評(píng)論 3 15
  • 1.分配更多的資源 -- 性能調(diào)優(yōu)的王道 真實(shí)項(xiàng)目里的腳本: bin/spark-submit \ --c...
    evan_355e閱讀 2,085評(píng)論 0 0
  • 1、重構(gòu)RDD架構(gòu)和RDD持久化 RDD架構(gòu)重構(gòu)與優(yōu)化盡量去復(fù)用RDD,差不多的RDD,可以抽取成一個(gè)共同的RDD...
    雪飄千里閱讀 1,114評(píng)論 0 1
  • 一、診斷內(nèi)存的消耗 1、spark內(nèi)存消耗 (1)java對(duì)象頭:包含一些對(duì)象的元信息。 (2)java的Stri...
    蠟筆小噺沒有煩惱閱讀 3,356評(píng)論 0 3
  • Apache Spark 是專為大規(guī)模數(shù)據(jù)處理而設(shè)計(jì)的快速通用的計(jì)算引擎。Spark是UC Berkeley AM...
    大佛愛讀書閱讀 2,980評(píng)論 0 20

友情鏈接更多精彩內(nèi)容