exchange 无权执行操作_技本功|Hive优化之Spark执行引擎参数调优(二)

d6e9c4bd961956548df2a9bd1afd6449.gif 0bdffabb9366e415d0c5a99877741030.png 作者: 九 月 袋鼠云大数据工程师

多年大数据运维/数仓开发经验,擅长数仓模型开发、平台运维;参与/主导金融/教育等客户的大数据数仓建设;负责多家客户的大数据业务场景落地。

d6e9c4bd961956548df2a9bd1afd6449.gif Hive是大数据领域常用的组件之一,主要是大数据离线数仓的运算,关于Hive的性能调优在日常工作和面试中是经常涉及的的一个点,因此掌握一些Hive调优是必不可少的一项技能。影响Hive效率的主要有数据倾斜、数据冗余、job的IO以及不同底层引擎配置情况和Hive本身参数和HiveSQL的执行等因素。 本文主要结合实际业务情况,在使用Spark作为底层引擎时,通过一些常见的配置参数对报错任务进行调整优化,主要包含以下两个方面:

01

Spark资源参数优化

主要针对Spark运行过程中各个使用资源的地方,通过调节资源相关参数,来优化资源使用的效率,从而提升Spark作业的执行性能。例如:num-executors、executor-memory、executor-cores等。

02

Shuffle相关参数调优

主要针对spark运行过程中的shuffle,通过调节参数,提高shuffle的执行效率,从而提升spark作业的执行性能。例如:spark.shuffle.memoryFraction,

spark.sql.shuffle.partitions等。

 案例1

某天晨间巡检,工程师发现有任务报错,任务sql大约有400行,较为复杂,join聚合函数操作较多。手动重试任务后仍然报错。

查看任务报错日志

dca958976a30453b3e682bebcfe5212d.png

分析关键信息

Exception in thread "broadcast-exchange-0" java.lang.OutOfMemoryError: Not enough memory to build and broadcast the table to all worker nodes. As a workaround, you can either disable broadcast by setting spark.sql.autoBroadcastJoinThreshold to -1 or increase the spark driver memory by setting spark.driver.memory to a higher value

得出结论

当前所有的工作节点均没有足够的内存去build并且广播表,建议处理方法:将广播置为无效或者增加spark的driver memory。

优化效果

经过对比测试验证,在同时调大excutor内存和driver内存后,任务可以成功运行。单独调大driver或excutor内存,任务运行依然失败。

Q

思考:什么情况下应将广播设置为无效?

答:根据官网文档对该参数的描述可知:其默认值为10M,意味着执行join时,这张表字节大小在10M内可以自动广播到所有工作节点。将表广播到其他工作节点,会减少shuffle的过程,提升效率。如果在内存足够并且数据量过多的情况下,可以将适当提高该参数值作为一种优化手段。如果在表都很大的情况下,建议将自动广播参数置为无效。将参数值设置为-1时会禁用自动广播。

7b695aa6f19c525f8bd6b446c003f134.png

 案例2 

某日工程师在编写客户运维日报时,发现某个任务已经运行了40多个小时,自动重试了3次,且处于阻塞状态。

查看异常任务SQL

发现任务中由10多个SQL语句构成,一个语句大概有200+行,union all、join、sum操作较多。

0dc2705f3a92cfe643c948ead15d616b.png

查看任务报错日志

e3600c06aae261eb62a44d369ff610f4.png

分析关键信息

org.apache.spark.shuffle.MetadataFetchFailedException: Missing an output location for shuffle 433

得出结论

一般任务有大量shuffle操作的时候,我们可以从shuffle数据量及shuffle分区数的角度对任务进行优化调整。

优化效果

只采取调大executor内存的方式进行优化,任务可以运行成功,但任务执行耗时仍然需20+分钟,执行效率与优化前相比无明显变化。原因在于任务执行中产生了较多的task,此时可以通过调整分区参数进行深入优化。分区参数spark.sql.shuffle.partitions是Spark SQL专用的设置,将该参数的值由200(默认值)调小为50,任务运行成功,执行耗时减少50%,约10分钟;继续将该参数调小为10,任务运行成功,执行耗时减少70%,约6分钟,优化完成。

Q

思考:spark.default.parallelism参数与

spark.sql.shuffle.partitions参数有什么区别?

答:虽然这两个参数较为相似,但default.parallelism只在处理RDD时才会起作用,对Spark SQL无效。其值设置为【num- executors * executor-cores】的2~3倍较为合理。可以参考官网的定义说明:

ba392a360a6e440acfbe412947d326fd.png

 延伸拓展 ·

1.shuffle分为shuffle write和shuffle read两部分。

2.shuffle write的分区数由上一阶段的RDD分区数控制,shuffle read的分区数则是由Spark提供的一些参数控制。

3.shuffle write可以简单理解为类似于saveAsLocalDiskFile的操作,将计算的中间结果按某种规则临时放到各个executor所在的本地磁盘上。

4.shuffle read时数据的分区数则是由spark提供的一些参数控制。如果这个参数值设置的很小,同时shuffle read的量很大,那么将会导致一个task需要处理的数据非常大,容易引发JVM crash。如果这个参数值设置的很大,可能会导致task的数量过多,任务执行速度过慢。

4310665698e636206e7712a44856cea5.png

job和stage以及task的关系如下图所示,job的划分是action操作造成的,Stage是job通过依赖关系划分出来的,一个Stage对应一个TaskSet,一个Task对应一个rdd分区。同时大量使用shuffle操作也会使task数量变多。

3d85f6a8d299c78340a0dacab0d223f1.png

写在最后

7b6ab35b9c7dc735608a9e57fa3c17ab.gif

本次优化主要是结合实际优化案例,对底层引擎spark的参数进行调优。如何通过优化提升任务执行效率?如何利用监控分析将被动运维转为主动运维?请关注后续Hive性能优化及监控方面的实践连载。

34a2c6fa6c3e1e1ccd7daa5bfc57d122.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值