您好,登錄后才能下訂單哦!
本篇文章為大家展示了怎么進行Spark性能優化指南得分析,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
一. Spark作業原理
我們使用spark-submit提交一個Spark作業之后,這個作業就會啟動一個對應的Driver進程。該進程是向集群管理器(Yarn,K8s)申請運行Spark作業需要使用的資源,這里的資源指的就是Executor進程。YARN集群管理器會根據我們為Spark作業設置的資源參數,在各個工作節點上,啟動一定數量的Executor進程,每個Executor進程都占有一定數量的內存和CPU core。
在申請到了作業執行所需的資源之后,Driver進程會將我們編寫的Spark作業代碼分拆為多個stage,每個stage執行一部分代碼片段,并為每個stage創建一批task,然后將這些task分配到各個Executor進程中執行。task是最小的計算單元,負責執行一模一樣的計算邏輯。一個stage的所有task都執行完畢之后,會在各個節點本地的磁盤文件中寫入計算中間結果,然后Driver就會調度運行下一個stage。
Spark是根據shuffle類算子來進行stage的劃分。如果我們的代碼中執行了某個shuffle類算子(比如reduceByKey、join等),那么就會在該算子處,劃分出一個stage界限來。可以大致理解為,shuffle算子執行之前的代碼會被劃分為一個stage,shuffle算子執行以及之后的代碼會被劃分為下一個stage。因此一個stage剛開始執行的時候,它的每個task可能都會從上一個stage的task所在的節點,去通過網絡傳輸拉取需要自己處理的所有key,然后對拉取到的所有相同的key使用我們自己編寫的算子函數執行聚合操作
當我們在代碼中執行了cache/persist等持久化操作時,根據我們選擇的持久化級別的不同,每個task計算出來的數據也會保存到Executor進程的內存或者所在節點的磁盤文件中。
因此Executor的內存主要分為三塊:
第一塊是讓task執行我們自己編寫的代碼時使用,默認是占Executor總內存的20%;
第二塊是讓task通過shuffle過程拉取了上一個stage的task的輸出后,進行聚合等操作時使用,默認也是占Executor總內存的20%;
第三塊是讓RDD持久化時使用,默認占Executor總內存的60%。
二.核心調優參數
num-executors:該參數用于設置Spark作業總共要用多少個Executor進程來執行。Driver在向YARN集群管理器申請資源時,YARN集群管理器會盡可能按照你的設置來在集群的各個工作節點上,啟動相應數量的Executor進程。這個參數非常之重要,如果不設置的話,默認只會給你啟動少量的Executor進程,此時你的Spark作業的運行速度是非常慢的。(建議50~100個左右的Executor進程)
executor-memory:該參數用于設置每個Executor進程的內存。Executor內存的大小,很多時候直接決定了Spark作業的性能,而且跟常見的JVM OOM異常,也有直接的關聯。(根據作業大小不同,建議設置4G~8G,num-executors乘以executor-memory,是不能超過隊列的最大內存量的)
executor-cores:該參數用于設置每個Executor進程的CPU core數量。這個參數決定了每個Executor進程并行執行task線程的能力。因為每個CPU core同一時間只能執行一個task線程,因此每個Executor進程的CPU core數量越多,越能夠快速地執行完分配給自己的所有task線程。(建議設置為2~4個,且num-executors * executor-cores不要超過隊列總CPU core的1/3~1/2)
driver-memory:該參數用于設置Driver進程的內存(建議設置512M到1G)。
spark.default.parallelism:該參數用于設置每個stage的默認task數量。這個參數極為重要,如果不設置可能會直接影響你的Spark作業性能。(建議為50~500左右,缺省情況下Spark自己根據底層HDFS的block數量來設置task的數量,默認是一個HDFS block對應一個task。Spark官網建議設置該參數為num-executors * executor-cores的2~3倍較為合適)
spark.storage.memoryFraction:該參數用于設置RDD持久化數據在Executor內存中能占的比例,默認是0.6(原則上是盡可能保證數據能夠全部在內存中,但如果發現作業發生頻繁的GC,就該考慮是否調小)
spark.shuffle.memoryFraction:該參數用于設置shuffle過程中一個task拉取到上個stage的task的輸出后,進行聚合操作時能夠使用的Executor內存的比例,默認是0.2。也就是說,Executor默認只有20%的內存用來進行該操作。shuffle操作在進行聚合時,如果發現使用的內存超出了這個20%的限制,那么多余的數據就會溢寫到磁盤文件中去,此時就會極大地降低性能。(shuffle操作較多時,建議降低持久化操作的內存占比,提高shuffle操作的內存占比比例,避免shuffle過程中數據過多時內存不夠用,必須溢寫到磁盤上,降低了性能)
上述內容就是怎么進行Spark性能優化指南得分析,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。