Spark性能调优1-测试记录

来源:互联网 发布:白人帅哥 知乎 编辑:程序博客网 时间:2024/05/22 06:39


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

0 0