調優步驟
廣播大變數
運算元優化
foreachpartition
repartition
儲存檔案優化
參考鏈結
隨緣求讚
關於spark程式優化總結,包括引數調優、rdd優化、運算元優化等。對於處理大資料量的spark程式而言,如果做好調優,將會有比較明顯的效果。從個人而言,是鍛鍊提公升自己的機會;從專案而言,是用最小的資源做最優的事情。下面是我在工作過程中遇到的調優記錄,可能不夠全面,不過學會了這些,一些簡單的調優還是沒什麼問題的。即使是菜鳥,一步步努力,不驕不躁,終會達到乙個比較好的高度!與君共勉之!
軟體版本
spark
1.6屬性名
預設值描述
spark.executor.instances
2靜態分配的executor數。 如果同時使用spark.dynamicallocation.enabled和spark.executor.instances時,則動態分配將會被關閉,將會使用spark.executor.instances的值
spark.executor.memory
1g每個executor程序使用的記憶體大小,格式與具有大小單位字尾(k,m,g,t)的jvm記憶體字串相同(1024m,2g)
spark.executor.cores
1每個executor使用的核心數
spark.executor.memoryoverhead
executormemory * 0.10, 最小為384
除非另有說明,否則每個executor要分配的堆外記憶體量(mib) 這是乙個記憶體,可以解決諸如vm開銷,以及其他本機開銷等問題。這往往會隨著執行程式的大小而增加(通常為6-10%)。 yarn和kubernetes目前支援此選項。
spark.sql.autobroadcastjointhreshold
10485760 (10 mb)
配置該錶在執行聯接時可以被廣播到所有工作程式節點的最大大小(以位元組為單位)。如果設定為-1,則廣播將會失效。請注意,當前統計資訊僅適用於已執行analyze table compute statistics noscan命令的hive metastore表
spark.shuffle.file.buffer
32kspark.reducer.maxsizeinflight
48m從每個reduce任務中同時獲取的對映輸出的最大大小。由於每個輸出都需要我們建立乙個緩衝區來接收它,因此這代表每個reduce任務固定的記憶體開銷,因此,請使其保持較小,除非有大量的記憶體。同理,如果記憶體較大,可以考慮調大該值,減少網路消耗
spark.shuffle.io.maxretries
3如果將其設定為非零值,則會自動重試由於與io相關的異常而失敗的提取。這種重試邏輯有助於在長時間的gc暫停或瞬態網路連線問題時穩定大資料量的shuffle。對於那些包含了特別耗時的shuffle操作的作業,建議增加重試最大次數,比如30次。
如果使用已有rdd進行轉換就可以得到想要的資料,就復用該rdd。
當同個rdd被重複呼叫action運算元的時候,每一次都會重新計算該運算元的父rdd。對同乙個rdd的重複計算是對資源的極大浪費,所以有必要進行資源的持久化。當記憶體無法將rdd的資料完整的進行存放的時候,可以考慮使用序列化的方式減小資料體積,將資料完整儲存在記憶體中。
如果task在執行過程中,有呼叫外部變數的話,那每乙個task在執行過程中,都會呼叫乙份變數儲存在本地,造成記憶體的極大消耗。那麼記憶體被消耗了,就會導致本來可以被持久化的資料沒辦法持久化,只能存放到磁碟,導致磁碟io變大,嚴重消耗資源。另一方面,記憶體逐漸被佔滿,當task要建立新變數的時候,記憶體不足,就會觸發gc。而gc會暫停工作執行緒,進而導致spark程序會暫停工作一行,從而嚴重影響spark效能。如果廣播了大變數,則每乙個executor都只會儲存乙份這樣的變數,每個task都會從本地的blockmanager獲取。
使用spark sql的時候,會自動根據資料進行動態分割槽。如果處理過程中,運算元的處理邏輯較為複雜,並且資料量較大,而spark sql設定的partition比較少,就會導致乙個問題:不多的task會處理該資料量大的partition,而且處理邏輯還比較複雜,進而導致處理速度緩慢。所以可以在使用spark sql,可以根據情況,適當地增大或者縮小該分割槽數量,從而調整處理並行度,進而加快處理速度。
如果是hive、spark sql結合使用的話,根據具體的情況使用對應的儲存檔案格式。在我的實際專案中,有兩種壓縮方式,一種是對普通文字檔案的lzo壓縮,一種是對parquet的gzip壓縮。如果是spark程式執行儲存表,一般指定表儲存方式為parquet檔案,然後在儲存過程中指定gzip壓縮。如果是hive指令碼跑數,則指定為普通文字檔案,並使用lzo進行壓縮。
下圖是我做的測試資料,表是相同的表,只是命名不同。字段資料量大概為20個左右。第乙個表是沒有做壓縮的資料大小,為69.8g;第二個表是做lzo壓縮方式,為24.7g;第三個表是使用了parquet的gzip壓縮方式,為12.8gb。一般lzo壓縮,可以壓縮到原來的三分之一,而parquet的gzip壓縮,根據資料的不同而呈現不同的壓縮比,我們的測試結果是可以壓縮到原來的百分之十八。另一方面,lzo壓縮,是對整個文字進行壓縮;而parquet檔案是列式儲存,在實際應用中,我們一般是只取表的幾列來進行運算,使用parquet儲存可以增加讀取效率。從下圖可以知道,parquet檔案壓縮的檔案,占用的計算資源更少,結果輸出更快。
表壓縮方式
儲存大小
執行時間
運算資源(reducers)
test_txt
無壓縮69.8g
429.12s
2771099
test_lzo
lzo壓縮
24.7g
450.37s
101396
test_d
parquet檔案gzip格式壓縮
12.8gb
364.04s
97206
spark docs
spark sql, dataframes and datasets guide
running spark on yarn
spark configuration
spark效能調優總結
1 序列化優化 使用高效能的序列化框架 kryo框架 大部分已經註冊 如果沒有註冊 而是自定義的類 sparkconf conf new sparkconf set spark.serializer org.apach.spark.serializer.kryoserializer 那麼要註冊 2 ...
spark調優 shuffle調優
基於spark1.6 引數可以通過 new sparkcontext set 來設定,也可以通過命令的引數設定 conf spark.shuffle.file.buffer 預設值 32k 引數說明 該引數用於設定shuffle write task的bufferedoutputstream的buf...
spark調優 shuffle調優
每乙個shuffle的前半部分stage的task,每個task都會建立下乙個stage的task數量相同的檔案,比如下乙個stage會有100個task,那麼當前stage每個task都會建立100份檔案,會將同乙個key對應的values,一定是寫入同乙個檔案中的,也一定會將同乙個key對應的v...