標籤:王家林談spark效能最佳化第一季!
內容:
1、Spark效能最佳化需要思考的基本問題;
2、CPU和Memory;
3、並行度和Task;
4、網路;
==========王家林每日大資料語錄============
王家林每日大資料語錄Spark篇0080(2016.1.26於深圳):如果Spark中CPU的使用率不夠高,可以考慮為當前的程式分配更多的Executor,或者增加更多的Worker執行個體來充分的使用多核的潛能。
王家林每日大資料語錄Spark篇0079(2016.1.26於深圳):適當設定Partition分區數是非常重要的,過少的Partition分區數可能會因為每個Partition資料量太大而導致OOM以及頻繁的GC,而過多的Partition分區資料可能會因為每個Partition資料量太小而導致執行效率低下。
王家林每日大資料語錄Spark篇0078(2016.1.23於深圳):提升Spark硬體尤其是CPU使用率的一個方式就是增加Executor的並行度,但是如果Executor過多的話,直接分配在每個Executor的記憶體就大大減少,在記憶體的操作就減少,基於磁碟的操作就越來越多,導致效能越來越差。
王家林每日大資料語錄Spark篇0077(2016.1.23於深圳):處理Spark Job時候如果發現比較容易記憶體溢出,另外一個比較有效辦法是減少並行的Executor數量,這樣每個Executor就可以分配到更多的記憶體,進而增加每個Task使用的記憶體數量,降低OOM的風險。
王家林每日大資料語錄Spark篇0076(2016.1.23於深圳):處理Spark Job時候如果發現比較容易記憶體溢出,一個比較有效辦法就是增加Task的並行度,這樣每個Task處理的Partition的資料量就變少了,減少了OOM的可能性。
王家林每日大資料語錄Spark篇0075(2016.1.23於深圳):處理Spark Job時候如果發現某些Task啟動並執行特別慢另外一個處理辦法是增加並行的Executor的個數,這樣每個Executor分配的計算資源就變少了,可以提升硬體的整體使用效率。
王家林每日大資料語錄Spark篇0074(2016.1.23於深圳):處理Spark Job時候如果發現某些Task啟動並執行特別慢,這個時候應該考慮增加任務的並行度,減少每個Partition的資料量來提高執行效率。
王家林每日大資料語錄Spark篇0073(2016.1.23於深圳):處理Spark Job的過程中如果出現特別多的小檔案,這時候就可以通過coalesce來減少Partition的數量,進而減少並行運算的Task的數量來減少過多任務的開闢,從而提升硬體的使用效率
王家林每日大資料語錄Spark篇0072(2016.1.22於深圳):預設情況下Spark的Executor會儘可能佔用當前機器上盡量多的Core,這樣帶來的一個好處就是可以最大化的提高計算的並行度,減少一個Job中任務啟動並執行批次,但帶來的一個風險就是如果每個Task佔用記憶體比較大,就需要頻繁的spill over或者有更多的OOM的風險。
王家林每日大資料語錄Spark篇0071(2016.1.22於深圳):Spark叢集在預設情況每台host上只有一個Worker,而每個Worker預設只會為當前應用程式分配一個Executor來執行Task,但實際上通過配置spark-env.sh可以讓每台host上有若干的Worker,而每個Worker下面又可以有若干個Executor。
王家林每日大資料語錄Spark篇0070(2016.1.22於深圳):Spark Stage內部是一組計算邏輯完全相同但處理資料不同的分布式並行啟動並執行Task構成 ,Stage內部的計算都以Pipeline的方式進行,不同的Stage之間是產生Shuffle的唯一方式。
王家林每日大資料語錄Spark篇0069(2016.1.21於深圳):在Spark中可以考慮在Worker節點上使用固態硬碟以及把Worker的Shuffle結構儲存到RAM Disk的方式來極大的提高效能。
==========Spark效能最佳化核心基石============
1、Spark是採用Master-Slaves的模型進行資源管理和任務執行的管理;
1)資源管理:Master-Workers,在一台機器上可以有多個Workers;
2)任務執行:Driver-Executors,當在一台機器上分配多個Workers的時候,那麼預設情況下每個Worker都會為當前啟動並執行應用程式分配一個Executor,但是我們可以修改配置來讓每個Worker為我們當前的應用程式分配若干個Executor,程式啟動並執行時候會被劃分成為若干個Stages(Stage內部沒有Shuffle,遇到Shuffle的時候會劃分Stage),每個Stage裡麵包含若干個處理邏輯完全一樣,知識處理的資料不一樣的Tasks,這些Tasks會被分配到Executor去執行;
2、在Spark中可以考慮在Worker節點上使用固態硬碟以及把Worker的Shuffle結構儲存到RAM Disk的方式來極大的提高效能;
3、預設情況下Spark的Executor會儘可能佔用當前機器上盡量多的Core,這樣帶來的一個好處就是可以最大化的提高計算的並行度,減少一個Job中任務啟動並執行批次,但帶來的一個風險就是如果每個Task佔用記憶體比較大,就需要頻繁的spill over或者有更多的OOM的風險;
4、當你經常發現機器頻繁的OOM的時候,可以考慮的一種方式就是減少並行度,這樣同樣的記憶體空間並行運算的任務少了,那麼對記憶體的佔用就更少了,也就減少了OOM的可能性;
5、處理Spark Job的過程中如果出現特別多的小檔案,這時候就可以通過coalesce來減少Partition的數量,進而減少並行運算的Task的數量來減少過多任務的開闢,從而提升硬體的使用效率;
6、處理Spark Job時候如果發現某些Task啟動並執行特別慢,這個時候應該考慮增加任務的並行度,減少每個Partition的資料量來提高執行效率;
7、處理Spark Job時候如果發現某些Task啟動並執行特別慢另外一個處理辦法是增加並行的Executor的個數,這樣每個Executor分配的計算資源就變少了,可以提升硬體的整體使用效率;
8、處理Spark Job時候如果發現比較容易記憶體溢出,另外一個比較有效辦法是減少並行的Executor數量,這樣每個Executor就可以分配到更多的記憶體,進而增加每個Task使用的記憶體數量,降低OOM的風險;
9、提升Spark硬體尤其是CPU使用率的一個方式就是增加Executor的並行度,但是如果Executor過多的話,直接分配在每個Executor的記憶體就大大減少,在記憶體的操作就減少,基於磁碟的操作就越來越多,導致效能越來越差;
10、適當設定Partition分區數是非常重要的,過少的Partition分區數可能會因為每個Partition資料量太大而導致OOM以及頻繁的GC,而過多的Partition分區資料可能會因為每個Partition資料量太小而導致執行效率低下;
11、如果Spark中CPU的使用率不夠高,可以考慮為當前的程式分配更多的Executor,或者增加更多的Worker執行個體來充分的使用多核的潛能;
12、實際執行Spark Job的時候要根據輸入資料和每個Executor分配的Memory來決定執行時候的並行度,實際上幾個簡單的事實,每個core可以考慮分配2~3個Task;
13、預設情況下,Executor的60%的記憶體被用來作為RDD的緩衝,40%的記憶體被用來作為對象的建立空間,設定是通過spark.storage.memoryFraction,預設是0.6;
14、假設資料是壓縮的,4個Task每個是128M的資料來源,解壓變成2倍,則記憶體是4*2*128M了,這樣可能就會記憶體溢出,不能光看HDFS現有大小多少的;
14、GC一般不能超過CPU的2%的時間(註:鎢絲計劃解決的核心問題之一就GC),比如出現錯誤OutOfMemoryErro,gc overhead limit exceeded;
總結:效能調優的有效性是暫時的,例如在為當前的應用程式增加Executor,可能在一開始可以提高效能(例如CPU使用率提高等),但是隨著Executor越來越多,效能可能會下降!!!因為Executor越來越多的時候,為每個Executor分配的記憶體就越來越少,Task在執行的時候可用的記憶體就越來越少,這個時候就要頻繁的spill over到磁碟,此時自然而然的導致效能變差;
舉例:
1、Job運行慢,CPU使用不是很高,這個時候考慮增加並行度或者分區數,其實也是增加CPU的利用率;
2、如果出現OOM,一般就是單個partition太大,考慮增大分區數;
3、一台機器上資源有限,如果為一台機器開闢過多的Executor,也有OOM的風險,這樣為每個Task分配的記憶體就變大了,也會減少OOM的風險;
4、有大量小檔案,導致效率低下,可以考慮減少檔案分區數;
5、無論如何要資料本地化,不能說HDFS在一個叢集,Spark在一個叢集,這樣就傻了。沒辦法只能這樣的時候,中間加個Tachyon;
最影響CPU的,就是並行度
很少把資料persist到磁碟上,經過測試發現如果把資料persist到磁碟上,有時候還不如重新計算快
在正式交付之前,要線上上調試至少1周,把效能調到最優。
實際啟動並執行時候會根據輸入和Executor來確定使用的core。
==========Spark效能最佳化招式============
1、BroadCast,如果Task在啟動並執行過程中使用超過20KB大小的靜態大對象,這個時候一般都要考慮使用broadcast,例如一個大表jion一個小表,可以考慮把小表broadcast出去,這樣大表只需要在自己的節點上待著靜靜等待小表的到來,這樣就可以減少Shuffle了,可能提高几十倍的效能;
王家林老師名片:
中國Spark第一人
新浪微博:http://weibo.com/ilovepains
公眾號:DT_Spark
部落格:http://blog.sina.com.cn/ilovepains
手機:18610086859
QQ:1740415547
郵箱:[email protected]
本文出自 “一枝花傲寒” 部落格,謝絕轉載!
王家林談Spark效能最佳化第一季!(DT大資料夢工廠)