1. 程式人生 > >Spark 性能相關參數配置具體解釋-任務調度篇

Spark 性能相關參數配置具體解釋-任務調度篇

div 設置 宋體 速度 意義 期望 簡單的 取數據 全局

作者:劉旭暉 Raymond 轉載請註明出處

Email:colorant at 163.com

BLOG:http://blog.csdn.net/colorant/


隨著Spark的逐漸成熟完好, 越來越多的可配置參數被加入到Spark中來, 本文試圖通過闡述這當中部分參數的工作原理和配置思路, 和大家一起探討一下怎樣依據實際場合對Spark進行配置優化。


因為篇幅較長。所以在這裏分篇組織,假設要看最新完整的網頁版內容。能夠戳這裏:http://spark-config.readthedocs.org/,主要是便於更新內容


schedule調度相關

調度相關的參數設置,大多數內容都非常直白,事實上無須過多的額外解釋。只是基於這些參數的經常使用性(大概會是你針對自己的集群第一步就會配置的參數),這裏多少就其內部機制做一些解釋。

spark.cores.max

一個集群最重要的參數之中的一個。當然就是CPU計算資源的數量。spark.cores.max 這個參數決定了在StandaloneMesos模式下,一個Spark應用程序所能申請的CPU Core的數量。假設你沒有並發跑多個Spark應用程序的需求,那麽能夠不須要設置這個參數,默認會使用spark.deploy.defaultCores的值(而spark.deploy.defaultCores的值默覺得Int.Max,也就是不限制的意思)從而應用程序能夠使用全部當前能夠獲得的CPU資源。

針對這個參數須要註意的是,這個參數對Yarn模式不起作用,YARN模式下,資源由

Yarn統一調度管理,一個應用啟動時所申請的CPU資源的數量由另外兩個直接配置Executor的數量和每一個Executorcore數量的參數決定。(歷史原因造成,不同執行模式下的一些啟動參數個人覺得還有待進一步整合)

此外,在Standalone模式等後臺分配CPU資源時,眼下的實現中,在spark.cores.max同意的範圍內。基本上是優先從每一個Worker中申請所能得到的最大數量的CPU core給每一個Executor。因此假設人工限制了所申請的Max Core的數量小於StandaloneMesos模式所管理的CPU數量。可能發生應用僅僅執行在集群中部分節點上的情況(因為部分節點所能提供的最大

CPU資源數量已經滿足應用的要求),而不是平均分布在集群中。通常這不會是太大的問題,可是假設涉及數據本地性的場合,有可能就會帶來一定的必須進行遠程數據讀取的情況發生。

理論上,這個問題能夠通過兩種途徑解決:一是StandaloneMesos的資源管理模塊自己主動依據節點資源情況,均勻分配和啟動Executor。二是和Yarn模式一樣,同意用戶指定和限制每一個ExecutorCore的數量。

社區中有一個PR試圖走另外一種途徑來解決相似的問題,只是截至我寫下這篇文檔為止(2014.8),還沒有被Merge

spark.task.cpus

這個參數在字面上的意思就是分配給每一個任務的CPU的數量,默覺得1。實際上。這個參數並不能真的控制每一個任務實際執行時所使用的CPU的數量,比方你能夠通過在任務內部創建額外的工作線程來使用很多其他的CPU(至少眼下為止,將來任務的執行環境能否通過LXC等技術來控制還不好說)。它所發揮的作用,僅僅是在作業調度時,每分配出一個任務時,對已使用的CPU資源進行計數。也就是說僅僅是理論上用來統計資源的使用情況,便於安排調度。因此,假設你期望通過改動這個參數來加快任務的執行,那還是趕緊換個思路吧。這個參數的意義。個人覺得還是在你真的在任務內部自己通過不論什麽手段,占用了很多其他的CPU資源時。讓調度行為更加準確的一個輔助手段。

spark.scheduler.mode

這個參數決定了單個Spark應用內部調度的時候使用FIFO模式還是Fair模式。是的,你沒有看錯。這個參數僅僅管理一個Spark應用內部的多個沒有依賴關系的Job作業的調度策略。

假設你須要的是多個Spark應用之間的調度策略,那麽在Standalone模式下,這取決於每一個應用所申請和獲得的CPU資源的數量(臨時沒有獲得資源的應用就Pending在那裏了),基本上就是FIFO形式的。誰先申請和獲得資源,誰就占用資源直到完畢。而在Yarn模式下。則多個Spark應用間的調度策略由Yarn自己的策略配置文件所決定。

那麽這個內部的調度邏輯有什麽用呢?假設你的Spark應用是通過服務的形式,為多個用戶提交作業的話,那麽能夠通過配置Fair模式相關參數來調整不同用戶作業的調度和資源分配優先級。

spark.locality.wait

spark.locality.wait和spark.locality.wait.process,spark.locality.wait.node, spark.locality.wait.rack這幾個參數影響了任務分配時的本地性策略的相關細節。

Spark中任務的處理須要考慮所涉及的數據的本地性的場合,基本就兩種,一是數據的來源是HadoopRDD; 二是RDD的數據來源來自於RDD Cache(即由CacheManagerBlockManager中讀取,或者Streaming數據源RDD)。

其他情況下。假設不涉及shuffle操作的RDD。不構成劃分StageTask的基準,不存在推斷Locality本地性的問題,而假設是ShuffleRDD,其本地性始終為No Prefer。因此事實上也無所謂Locality

在理想的情況下。任務當然是分配在能夠從本地讀取數據的節點上時(同一個JVM內部或同一臺物理機器內部)的執行時性能最佳。

可是每一個任務的執行速度無法準確預計,所以非常難在事先獲得全局最優的執行策略,當Spark應用得到一個計算資源的時候。假設沒有能夠滿足最佳本地性需求的任務能夠執行時,是退而求其次。執行一個本地性條件稍差一點的任務呢。還是繼續等待下一個可用的計算資源已期望它能更好的匹配任務的本地性呢?

這幾個參數一起決定了Spark任務調度在得到分配任務時,選擇臨時不分配任務,而是等待獲得滿足進程內部/節點內部/機架內部這種不同層次的本地性資源的最長等待時間。

默認都是3000毫秒。

基本上。假設你的任務數量較大和單個任務執行時間比較長的情況下,單個任務是否在數據本地執行,代價差別可能比較顯著,假設數據本地性不理想。那麽調大這些參數對於性能優化可能會有一定的優點。反之假設等待的代價超過帶來的收益,那就不要考慮了。

特別值得註意的是:在處理應用剛啟動後提交的第一批任務時,因為當作業調度模塊開始工作時,處理任務的Executors可能還沒有全然註冊完畢。因此一部分的任務會被放置到No Prefer的隊列中。這部分任務的優先級僅次於數據本地性滿足Process級別的任務,從而被優先分配到非本地節點執行。假設的確沒有Executors在相應的節點上執行,或者的確是No Prefer的任務(如shuffleRDD)。這樣做確實是比較優化的選擇。可是這裏的實際情況僅僅是這部分Executors還沒來得及註冊上而已。這種情況下,即使加大本節中這幾個參數的數值也沒有幫助。針對這個情況。有一些已經完畢的和正在進行中的PR通過比如動態調整No Prefer隊列,監控節點註冊比例等等方式試圖來給出更加智能的解決方式。只是,你也能夠依據自身集群的啟動情況。通過在創建SparkContext之後,主動Sleep幾秒的方式來簡單的解決問題。

spark.speculation

spark.speculation以及spark.speculation.interval,spark.speculation.quantile, spark.speculation.multiplier等參數調整Speculation行為的詳細細節,Speculation是在任務調度的時候,假設沒有適合當前本地性要求的任務可供執行。將跑得慢的任務在空暇計算資源上再度調度的行為。這些參數調整這些行為的頻率和推斷指標,默認是不使用Speculation的。

通常來說非常難正確的推斷是否須要Speculation,能真正發揮Speculation用處的場合。往往是某些節點因為執行環境原因。比方CPU資源因為某種原因被占用。磁盤損壞導致IO緩慢造成任務執行速度異常的情況,當然前提是你的分區任務不存在僅能被執行一次,或者不能同一時候執行多個拷貝等情況。Speculation任務參照的指標一般是其他任務的執行時間。而實際的任務可能因為分區數據尺寸不均勻,本來就會有時間差異,加上一定的調度和IO的隨機性,所以假設一致性指標定得過嚴,Speculation可能並不能真的發現問題,反而添加了不必要的任務開銷,定得過寬。大概又基本相當於沒用。

個人覺得。假設你的集群規模比較大,執行環境復雜,的確可能經常發生執行異常,加上數據分區尺寸差異不大。為了程序執行時間的穩定性,那麽能夠考慮細致調整這些參數。否則還是考慮怎樣排除造成任務執行速度異常的因數比較靠鋪一些。

當然,我沒有實際在非常大規模的集群上執行過Spark,所以假設看法有些偏頗。還請有實際經驗的XD指正。


Spark 性能相關參數配置具體解釋-任務調度篇