您好,登錄后才能下訂單哦!
如何理解spark調(diào)優(yōu)中的高層通用調(diào)優(yōu),很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。
一,并行度
集群不會(huì)被充分利用,除非您將每個(gè)操作的并行級(jí)別設(shè)置得足夠高。Spark自動(dòng)會(huì)根據(jù)文件的大小,是否可分割等因素來(lái)設(shè)置map的數(shù)目(后面會(huì)詳細(xì)講解輸入格式,同時(shí)詳細(xì)講解各種輸入的map數(shù)的決定)。對(duì)于分布式reduce操作,例如groupbykey和reducebykey,默認(rèn)它使用的是分區(qū)數(shù)最大的父RDD的分區(qū)數(shù)決定reduce的數(shù)目。你也可以通過(guò)設(shè)置spark.default.parallelism來(lái)改變默認(rèn)值,建議值是每個(gè)CPU執(zhí)行2-3個(gè)tasks。
二,Reduce任務(wù)的內(nèi)存使用
有時(shí)候內(nèi)存溢出并不是由于你的RDD不適合放在內(nèi)存里面,而是由于你的某個(gè)task的工作集太大了,比如使用groupbykey的時(shí)候reduce任務(wù)數(shù)據(jù)集太大了。Spark的shuffle操作(sortByKey, groupByKey, reduceByKey, join, etc)會(huì)構(gòu)建一個(gè)hash表,每個(gè)task執(zhí)行一個(gè)分組的數(shù)據(jù),單個(gè)往往會(huì)很大。最簡(jiǎn)單的改善方法是增加并行度,讓每個(gè)task的輸入變得更小。Spark可以高效的支持短達(dá)200ms的任務(wù),因?yàn)閺?fù)用了Executor的JVM,這可以降低啟動(dòng)成本,所以你可以很安全的增加并行度,使其超過(guò)你的集群core數(shù)目。
三,廣播變量
使用spark的廣播功能可以大幅度減少每個(gè)序列化后的task的大小,也可以減少在集群中執(zhí)行一個(gè)job的代價(jià)。如果你的任務(wù)中使用了大的對(duì)象,比如靜態(tài)表,可以考慮將它聲明成廣播變量。在driver節(jié)點(diǎn),spark會(huì)打印出每個(gè)task序列化后的大小,所以你可以通過(guò)查看task的大小判斷你的task是否過(guò)大,通常task的大小超過(guò)20KB就值得調(diào)優(yōu)了。
四,數(shù)據(jù)本地性
數(shù)據(jù)的本地性可能會(huì)對(duì)Spark jobs產(chǎn)生重大影響。如果數(shù)據(jù)和在其上操作的代碼在一起,則計(jì)算往往是快速的。但如果代碼和數(shù)據(jù)分開(kāi),則必須要有一方進(jìn)行移動(dòng)。典型的情況是將序列化后的代碼移動(dòng)到數(shù)據(jù)所在的地方,因?yàn)閿?shù)據(jù)往往比代碼大很多。Spark構(gòu)建調(diào)度計(jì)劃的原則就是數(shù)據(jù)本地性。
數(shù)據(jù)本地性就是數(shù)據(jù)離處理他的代碼有多遠(yuǎn)。根據(jù)數(shù)據(jù)和代碼當(dāng)前的位置,數(shù)據(jù)本地性等級(jí)。從最近到最遠(yuǎn)的順序列出如下:
1,PROCESS_LOCAL
數(shù)據(jù)和代碼在同一個(gè)JVM中,這是最佳的數(shù)據(jù)本地性。
2,NODE_LOCAL
數(shù)據(jù)和代碼在相同的節(jié)點(diǎn)。比如數(shù)據(jù)在同一節(jié)點(diǎn)的HDFS上,或者在統(tǒng)一節(jié)點(diǎn)的Executor上。由于數(shù)據(jù)要在多個(gè)進(jìn)程間移動(dòng),所以比PROCESS_LOCAL稍慢。
3,NO_PREF
數(shù)據(jù)可以從任何地方快速訪問(wèn),沒(méi)有數(shù)據(jù)本地性。
4,RACK_LOCAL
數(shù)據(jù)和代碼在相同的機(jī)架。數(shù)據(jù)位于同一機(jī)架上的不同服務(wù)器上,因此需要通過(guò)網(wǎng)絡(luò)發(fā)送,通常通過(guò)單個(gè)交換機(jī)發(fā)送
5,ANY
數(shù)據(jù)在網(wǎng)絡(luò)上的其他地方,而不在同一個(gè)機(jī)架中。
Spark傾向于調(diào)度任務(wù)依據(jù)最高的數(shù)據(jù)本地性,但這往往是不可能的。在任何空閑的Executor上沒(méi)有未處理數(shù)據(jù)的情況下,Spark會(huì)切換到較低的數(shù)據(jù)本地性。這種情況下會(huì)有兩個(gè)選擇:
1),等待CPU空閑,然后在相同的server上啟動(dòng)task。
2),立即在一個(gè)需要遷移數(shù)據(jù)的較遠(yuǎn)位置啟動(dòng)一個(gè)新的task。
Spark的典型處理策略是等待繁忙CPU釋放,時(shí)間很短。一旦超時(shí),將移動(dòng)數(shù)據(jù)到空閑CPU的地方執(zhí)行任務(wù)。每個(gè)級(jí)別之間的回退等待超時(shí)可以在一個(gè)參數(shù)中單獨(dú)配置或全部配置。如果任務(wù)較長(zhǎng),且數(shù)據(jù)本地性較差,可以適當(dāng)調(diào)整Spark.locatity超時(shí)時(shí)間相關(guān)的配置。具體配置如下:
屬性 | 默認(rèn)值 | 含義 |
spark.locality.wait | 3s | 超時(shí)時(shí)間,放棄等待在較低數(shù)據(jù)本地性新啟任務(wù)。 |
spark.locality.wait.node | spark.locality.wait | NODE_LOCAL等待超時(shí)時(shí)間 |
spark.locality.wait.process | spark.locality.wait | PROCESS_LOCAL等待超時(shí)時(shí)間 |
spark.locality.wait.rack | spark.locality.wait | RACK_LOCAL等待超時(shí)時(shí)間 |
主要調(diào)優(yōu)就是序列化和內(nèi)存調(diào)優(yōu)。
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。