Spark性能調優1-測試記錄

 

1、調優背景

    Spark作爲Zeppelin的SQL底層執行引擎,通過Thriftserver處理jdbc連接,爲提高硬件資源利用率、IO帶寬和內存利用率,特針對性的進行Spark性能調優,目的是提高多租戶環境下Spark SQL執行效率。

 

2、整體調優結果

表2-1 整體調優結果

sql NO.

MR

sp-1(s)

sp-2(p)

sp-3(ec)

sp-4(or)

sp-5

sql1

690

71

37.7

29.5

29.2

27.4s

sql2

428.2

96.6

61

32.3

31.6

33.5

sql3

192.5

138.5

47.3

35.4

37.3

35.4

sql4

188

154.

76.8

51.7

49.5

48.8

sql5

1409

393

265

184

179.5

231

sql6

580.6

147.7

173

52

53.4

43.5

sql7

9128.5

2467

1240

1176

1258

1274

sql8

216

21

40

18.1

18.7

21.5

sql9

404

127

113

116.2

112.5

117.4

    調優隨機選取線上9條SQL,表橫軸是調優測試項目,測試在集羣空閒情況下進行,後一個的測試都是疊加前面測試參數。從數據可參數經過調優,理想環境下性能相對Spark默認參數可提高50%到300%。

表2-2 調優項目說明

測試項目

說明

MR

使用Hive測試

sp-1

默認spark參數測試

sp-2

spark.sql.shuffle.partitions參數

sp-3

executor與core參數比例

sp-4

spark.shuffle.*參數

sp-5

spark.sql.files.openCostInBytes參數

           主要調優參數就是這幾個,實際調優參數不止這幾個,下文將說明。此外因爲Spark現在默認開啓tungsten,所以省略tungsten調參。

 

3、單個參數調優記錄

1)並行度測試記錄

表3-1 並行度調優結果

sql NO.

200 partitions

400 partitions

600 partitions

sql1

71

50

37.7

sql2

96.6

95

61

sql3

138.5

126

47.3

sql4

154.

179

76.8

sql5

393

303.8

265

sql6

147.7

186

173

sql7

2467

1626

1240

sql8

232.7

37

40

sql9

127

136

113

 

    從調優結果和參考其他公司提供的信息看,對於公司數據規模,增大並行度有明顯的性能提高,而且從sql7的數據看出,增大並行度,對大SQL性能提升效果顯著。

 

2)core和memory比例測試記錄

           本測試的分區數爲600,主要測試executor的core和memory比例,core越多,能同時處理的task越多。

表3-2 core和memory比例測試結果

 

1core,4G

2core,6G

2core,7G 

2core ,8G

3core,6G

3core,9G

sql1

37.7

30

44

29.5

78.6

30

sql6

61

122

107

164

377

144

sql7

1240

failed

failed

1176

failed

failed

 

    1core對應4G是集羣初始參數配置,這裏選取3條典型sql記錄詳細測試結果,根據比較發現1core 對3G內存對中小sql能跑通,對稍大sql(如sql7)則直接因爲內存不足failed,考慮到實際測試其他公司推薦參數,最佳配比是2core對應8G內存,能更好利用core和mem(這裏內存其實越大肯定越好)。

 

3)spark shuffle測試記錄

    這裏涉及參數主要是spark.shuffle.file.buffer和spark.reducer.maxSizeInFlight。其中spark.shuffle.file.buffer主要負責shuffle write過程寫數據到磁盤過程的buffer,如果內存大的話建議提高該參數;spark.reducer.maxSizeInFlight負責shuffle read過程中reduce端機器從map端機器同時讀取數據的大小。

表 3-3 spark shuffle測試記錄

sql NO.

file.buffer=32k(默認),maxSizeInFlight=48M

file.buffer=48k,maxSizeInFlight=64M

sql1

29.5

29.2

sql2

32.3

31.6

sql3

35.4

37.3

sql4

51.7

49.5

sql5

184

179.5

sql6

52

53.4

sql7

1176

1258

sql8

18.1

18.7

sql9

116.2

112.5

 

    比較測試結果可以發現,提高buffer對執行時間沒有顯著影響,而由理論和其他公司經驗,提高buffer是能提高執行效率的。經分析發現集羣配置2core對應的8G內存是很保守的,shuffle過程的連接數有M * R個,每個連接都有一個buffer,對應消耗內存不小,對內存本就喫緊的job因內存不足,影響執行效率,由於內存約束,增加該shuffle參數對job執行時間沒有顯著影響。

 

4)spark.sql.files.openCostInBytes參數調優

    該參數默認4M,表示小於4M的小文件會合併到一個分區中,用於減小小文件,防止太多單個小文件佔一個分區情況。

表3-4spark.sql.files.openCostInByte測試記錄

sql NO.

spark.sql.files.openCostInByte = 4M

spark.sql.files.openCostInBytes = 8M

sql1

29.2

27.4s

sql2

31.6

33.5

sql3

37.3

35.4

sql4

49.5

48.8

sql5

179.5

231

sql6

53.4

43.5

sql7

1258

1274

sql8

18.7

21.5

sql9

112.5

117.4

 

    由數據比較可見,對job執行效率有一定提升,但是對於sql5則效率降低,經分析sql5每個分區的input大小是7.5M左右,在參數臨界位置附近,反而降低執行效果。但是對於小SQL,可能有少量性能提升。

 

 

4、其他調優測試

1)數據本地性調優

   涉及參數有spark.locality.wait.process,spark.locality.wait.node, spark.locality.wait.rack,分別是計算進程內、節點內、機架數據本地性的超時時間間隔,在集羣繁忙的時候網絡會不暢通,提高該值會有效提高數據locality比例,但是太高則會造成等待時間過長。

 

表4-1 不同locality情況下執行時間情況

sql

locality情況

執行時間(s)

Node local

Rack local

Any

sql1

214

232

0

140.2

326

122

0

26.4

sql6

52067

1492

635

139

49456

1392

142

41

49998

1380

53

36

 

    從表中結果可以明顯看出,locality級別越高(即計算離數據越近),job執行時間越短,因此調節這組參數對提高job執行時間有明顯效果,因爲能減小網絡傳輸開銷,提高執行效率。

 

2)數據格式對查詢效率影響測試

    spark.sql.hive.convertCTAS默認爲false,如果爲true則表示用戶創建的表使用parquet格式,下面測試不同數據格式建表的存儲大小和查詢時間記錄。

表4-2 不用格式對查詢影響

 

格式

讀取數據量(KB)

存儲大小(byte)

查詢時間(s)

sql-10

text

1167.5

1164841

10.5

orc

1028.3

572035

10.9

parquet

1083

1093378

10.7

 

sql-11

text

41.7

42687

7.8

orc

33.1

25841

4.3

parquet

21.7

45112

4.9

    由表看出,orc格式的存儲效率最佳,查詢時間性能也比較好。考慮開啓參數,建表默認使用orc格式。

 

3)spark.executor.overhead.memory參數測試記錄

           下面兩張表從不同維度看堆外內存參數對計算的影響。

表4-3 overheadmemory不同值調優記錄

spark.yarn.executor.overhead

200 partitions

400 partitions

512M

failed

522

1024M

393

303.8

    由數據可以看出,當overheadmemory內存比較小(512M)時增大分區能緩解計算壓力,讓計算成功執行。

 

表4-4 overheadmemory=512M情況測試記錄

SQL

200partitions

400partitions

SQL4

288.7

199.1

SQL5

failed

522

    表4-4驗證了表4-3測試的觀點。

 

4)對sql7最佳性能調優的記錄

    本測試作爲實驗性質,針對大SQL進行調優,目的是尋找大SQL調優的極限。

表4-5 sql7最佳性能調優

sql7參數

stage1併發數

執行時間

1core,4G,200partitiions,1G executor.memoryOverhead

/

2467

2core,8Gmem,600partitions,1G executor.memoryOverhead

2160

failed

2core,12Gmem,1500partitions,1G executor.memoryOverhead

1280

1308

2core,12Gmem,3500partitions,1G executor.memoryOverhead

1280

1132

3core,12Gmem,3500partitions,,2G executor.memoryOverhead

1748

986

3core,8Gmem,3500partitions,2G executor.memoryOverhead

2160

954

3core,8Gmem,5000partitions,2G executor.memoryOverhead

2160

838.1

 

    這裏因爲時間因素,沒繼續往下調,但從調優實驗結果看,合理的core,mem比例以及並行度是能顯著提升執行效率,從2000多秒到800多秒,達到300%提升。

 

5、Zeppelin用戶調優參數

           經過調優測試,SQL用戶在寫SQL中可以調節的參數如下表彙總。

表4-6 SQL用戶可調節參數

參數

說明

spark.sql.shuffle.partitions

對於大SQL,提高該值顯著提升執行效率和穩定性

spark.sql.autoBroadcastJoinThreshold

對於大表join小表,當數據級差距明顯時可增大該閾值,能減小網絡數據拉取開銷

spark.dynamicAllocation.enabled

該特性用於join操作,目的是實現無shuffle的join,不是對所有SQL有效,調整爲true可開啓該特性

 

 

   SQL用戶通過設置這幾個參數,能一定程度提高SQL執行效率和穩定性。

 

6、GC調優

    這裏根據調研,有效的參數主要是InitiatingHeapOccupancyPercent,表示ConcGCThreads和G1HeapRegionSize調優記錄如下表:

表6-1 GC調優記錄 

 

序號

InitiatingHeapOccupancyPercent

ConcGCThreads

G1HeapRegionSize

SQL

時間

1

45(默認)

5(默認)

2(默認)

sql12

485

sql13

387

2

35

15

2

sql12

458

sql13

335

3

35

15

4

sql12

451

sql13

334

4

35

15

6

sql12

489

sql13

297

 

 

表6-2 GC1日誌分析指標

 

 

Throughput

Avg GC Time

Max GC Time

Total GC Count

Total GC Time

G1 Humongous Allocation

Allocation Failure

1

99.4%

8ms

70ms

118

920ms

40

7

2

98.24%

12ms

120ms

277

3420ms

141

33

3

99.65%

11ms

70ms

85

910ms

24

17

4

99.4%

11ms

70ms

146

1550ms

67

20

 

 

 

 備註:GC分析日誌通過http://gceasy.io分析得出

    該測試在測試集羣進行,使用倉庫的兩張表作爲測試用例,根據執行結果,發現不同參數對執行時間影響不大,但是根據執行時間和GC日誌分析的指標,推薦第三組參數。

 

7、總結

    調優參數雖名目多樣,但最終目的是提高CPU利用率,降低帶寬IO,提高緩存命中率,減少數據落盤。

    不同數據量的最優參數都不相同,調優目的是讓參數適應數據的量級以最大程度利用資源,經調優發現並不是所有參數有效,有的參數的效果也不明顯,最後折中推薦如下調優參數以適應絕大多數SQL情況,個別SQL需要用戶單獨調參優化。(以下參數主要用於Spark Thriftserver)

 

表7-1 調優參數值

參數

含義

默認值

調優值

spark.sql.shuffle.partitions

併發度

200

800

spark.executor.overhead.memory

executor堆外內存

512m

1.5G

spark.executor.memory

executor堆內存

1G

9G

spark.executor.cores

executor擁有的core數

1

3

spark.locality.wait.process

進程內等待時間

3

3

spark.locality.wait.node

節點內等待時間

3

8

spark.locality.wait.rack

機架內等待時間

3

5

spark.rpc.askTimeout

rpc超時時間

10

1000

spark.sql.autoBroadcastJoinThreshold

小表需要broadcast的大小閾值

10485760

33554432

spark.sql.hive.convertCTAS

創建表是否使用默認格式

false

true

spark.sql.sources.default

默認數據源格式

parquet

orc

spark.sql.files.openCostInBytes

小文件合併閾值

4194304

6291456

spark.sql.orc.filterPushdown

orc格式表是否謂詞下推

false

true

spark.shuffle.sort.bypassMergeThreshold

shuffle read task閾值,小於該值則shuffle write過程不進行排序

200

600

spark.shuffle.io.retryWait

每次重試拉取數據的等待間隔

5

30

spark.shuffle.io.maxRetries

拉取數據重試次數

3

10

       

        任何參數設置都不可能對所有SQl有效,這裏的推薦參數主要針對公司中小SQL(執行時間不超過10分鐘)適用,對於大SQL如sql7則需單獨調參才能高效運行。以上測試均爲公司實際環境進行 。

 

測試環境:600+物理機集羣,spark 2.0.1 on yarn

 

**文章會同步到公衆號,關注公衆號,交流更方便:**


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章