1 前言
由于未经声明的参数行为变化, 2.3.0的性能对比惨到不行。本轮测试在之前的基础上对2.3.0加上额外的参数设置spark.sql.statistics.fallBackToHdfs true
进行新一轮的性能测试,以期望令人满意的结果。
2 测试数据
benchmark | scale | fileformat | partitioned | link |
---|---|---|---|---|
TPCDS | 1T | parquet | true | https://github.com/yaooqinn/tpcds-for-spark |
3 实验对象
3.1 参照组
baseline | modified | commit | link |
---|---|---|---|
2.1.2 | true | 9ef23ae | https://github.com/yaooqinn/spark/tree/v2.1.2-based |
3.2 实验组
baseline | modified | commit | link |
---|---|---|---|
2.3.0 | false | 992447f | https://github.com/yaooqinn/spark/tree/v2.3.0-based |
4 配置
4.1 硬件配置
机器类别 | CPU | Memory | Disk | 台数 | Services |
---|---|---|---|---|---|
虚拟机 | 4 × 1 × 1 | 32g | 500g × 1 | 5 | NN(1) SNN (1) RM(1) HMS(1) SHS(1) |
物理机 | 48 × 2 × 12 | 256g | 7.3T × 12 | 3 | DN(3) NM(3) |
物理机 | 48 × 2× 12 | 256g | 1.1T × 1 | 4 | DN(4) NM(4) |
物理机 | 32 × 2 × 8 | 128g | 3.6T × 12 | 1 | DN(1) NM(1) |
物理机 | 40 × 2 × 10 | 256g | 500g × 1 | 1 | NM(1) |
物理机 | 48 × 2 × 12 | 32g | 1.1T × 1 | 1 | DN(1) |
4.2 metrics
hdfs
yarn
4.3 SparkConf
## Basic Settings ##spark.master yarn spark.submit.deployMode client spark.serializer org.apache.spark.serializer.KryoSerializer spark.kryoserializer.buffer.max 256m spark.local.dir ./local## Hadoop Settings ##spark.hadoop.fs.hdfs.impl.disable.cache truespark.hadoop.fs.file.impl.disable.cache true## Driver/AM Settings ##spark.yarn.am.cores 2 spark.yarn.am.memory 2g spark.yarn.am.memoryOverhead 512 spark.yarn.am.extraJavaOptions -XX:PermSize=1024m -XX:MaxPermSize=2048m -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution spark.driver.maxResultSize 2g spark.driver.memory 30g spark.driver.extraJavaOptions -XX:PermSize=1024m -XX:MaxPermSize=1024m## Executor Settings ##spark.executor.instances 40 spark.executor.cores 4 spark.executor.memory 20g spark.executor.memoryOverhead 4096 spark.executor.extraJavaOptions -XX:PermSize=1024m -XX:MaxPermSize=1024m -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution## Security Settings ##spark.yarn.keytab ? spark.yarn.principal ?## Dynamic Allocation Settings ##spark.shuffle.service.enabled truespark.dynamicAllocation.enabled falsespark.dynamicAllocation.initialExecutors 1 spark.dynamicAllocation.minExecutors 1 spark.dynamicAllocation.maxExecutors 50## SQL Configurations ##spark.sql.autoBroadcastJoinThreshold 204857600 spark.sql.warehouse.dir /user/spark/warehouse# spark.sql.hive.convertCTAS true# spark.sql.sources.default parquetspark.sql.shuffle.partitions 1024# spark.sql.hive.convertMetastoreParquet falsespark.sql.crossJoin.enabled=true## History Server Client Settings ### spark.eventLog.enabled truespark.eventLog.compress truespark.eventLog.dir hdfs:///spark2-history/ spark.yarn.historyServer.address ?:18081
spark 2.3.0加上该配置
spark.sql.statistics.fallBackToHdfs true
5 测试结果
5.1 实验数据
实验数据
显示规则
列1:sql statement
列2:参照组结果
列3:实验组结果
显示规则见上图
5.2 定性结果
query19在参照组下没跑出结果,失误,没记下log。
query 77 两组皆未出结果,
spark.driver.maxResultSize 2g
设置太小测试只run了一轮,所以结果并不是十分严谨,[-0.1, 0.1]之间,就认为性能相当
可以看到本轮测试,实验组的性能相比前一轮测试有大幅度的提升,说明诸多SQL都由SortMerge转成了Broadcast
但是总体上而言,刨去“小查询”,依然有Query 9 72 88 等感受到了明显的下降。
query 72 怎么又有你?还能不能玩了?
性能提升是应该的,性能下降就打脸了。
6 相关分析
6.1 执行计划
quey 72 physical plan comparation
上图显示实验组在加上fallback参数后,逻辑计划除了长相不一样,但逻辑结构上已经一致了。
6.2 Job Metics对比
参照组 Job Metrics
实验组 Job Metrics
两轮Applications的所有Job没有task失败的记录运行良好
Job Id 11是两者性能的分水岭
6.3 Stage Metrics
参照组Stage Metrics
实验组Stage Metrics
参照组的13、实验组的14,实为同一个Stage,主要的时差在此
参照组Stage Metrics
实验组Stage Metrics
各项参数基本一致或者完全一致,除了Duration这一下,实验组完完全全的落后
参照组 DAG
实验组 DAG
比较两者的DAG完全一致,逻辑上没问题,问题的原因就可能是对应的物理算子,或者Spark Core的改动产生的性能regression了。或者是我维护的分支不小心加了性能优化特性[吃了一惊的表情]
6.4 Task Metrics
参照组 Task Id 5619
实验组 Task Id 5619
运气不错 Task ID 5619正巧排序后都在第一位,可以看到性能问题真正就是在task的执行过程慢,也基本印证上面6.3(3)的推断
6.5 日志分析
日志对比5619 assigned to finished 左侧参照组 右侧实验组
接上 日志对比5619 assigned to finished
截取5619从开始到结束段的executor日志进行对比
执行节点恰好一致
与之并行的相关task也一致的调度与该节点
shuffle service的server也一致
图中红框处,参照组Executor出现1分钟左右间隔,而实验组Executor出现3分钟左右的间隔,这时段基本可以理解为task正在吭哧吭哧的执行。
6.6 执行计划 VS DAG
DAG
对比执行计划 Stage14 为最后一个SortMergeJoin的右表,对应我们Stage 13就是在做Sort的左表(中间表)
所以基本可以猜测
SortExec
在2.3.0有性能regression,由于跨过了2.2相关的版本,所以并不能确定引入的时间点。
7 总结
对于那些没有Hive Statistics和Spark Statistics信息的表,需要注意在2.3.0之后
spark.sql.statistics.fallBackToHdfs true
去fallback,当然最好还是能去执行analyze来生成。SortExec
物理算子应该极有可能有性能regression,需要看代码/PR的变更。后续有时间可以再带点分享。有兴趣的可以根据本文提供的线索去分析一下,如果是的话可以贡献社区。
8 后记
蜀道难,还能不能玩了?
作者:风景不美
链接:https://www.jianshu.com/p/82006ea4ca71