记一次Spark引擎执行Sql超时优化

前几天用spark引擎执行了一个较大的sql,涉及的表和数据量都不少,不同时间段执行了几次都超时,经过上网及分析,尝试解决了此问题,使用spark引擎测试几次大概都在半个小时左右完成,不再出现超时现象

一、问题现象

摘抄部分现场日志如下:


2022-02-01 13:02:12 INFO 22/02/01 13:02:12 [dag-scheduler-event-loop] INFO DAGScheduler: ShuffleMapStage 28 (run at ThreadPoolExecutor.java:1149) finished in 569.587 s
2022-02-01 13:02:12 INFO 22/02/01 13:02:12 [dag-scheduler-event-loop] INFO DAGScheduler: looking for newly runnable stages
2022-02-01 13:02:12 INFO 22/02/01 13:02:12 [dag-scheduler-event-loop] INFO DAGScheduler: running: Set(ShuffleMapStage 13, ShuffleMapStage 5, ShuffleMapStage 22, ShuffleMapStage 14)
2022-02-01 13:02:12 INFO 22/02/01 13:02:12 [dag-scheduler-event-loop] INFO DAGScheduler: failed: Set()

Caused by: org.apache.spark.SparkException: Could not execute broadcast in 600 secs. You can increase the timeout for broadcasts via spark.sql.broadcastTimeout or spark.sql.broadcastMaxRetries or disable broadcast join by setting spark.sql.autoBroadcastJoinThreshold to -1

2022-02-01 13:02:14 WARNING spark-sql运行异常!
2022-02-01 13:02:14 WARNING 将会使用hive重试!


二、分析问题

从上述日志中可以看出在ShuffleMapStage阶段,也就是ShuffleRead阶段,在Driver在向各个Executor广播输入数据时候,出现了超时现象,容错机制自动启动了hive引擎重新执行,hive引擎经过数较长一段时间完成了,但也出现了reduce阶段的数据倾斜。

既然出现了超时,要么增加超时时间,设置更长的超时时间,要么重试一下,也可能是当时网络原因导致的,要么在超时时间内增大吞吐处理能力

简单从以下为以下几个方面着手:

1、适当增加超时时间

2、适当增加重试次数

3、加快处理速度

4、禁用BroadcastJoin

看到日志中给出 disable broadcast join by setting spark.sql.autoBroadcastJoinThreshold to -1,spark.sql.autoBroadcastJoinThreshold参数默认值是10M,小于设置的此值小表将不能被广播,将,设置为-1是禁用了BroadcastJoin方式广播

此方式没有尝试过,至于禁用BroadcastJoin后,会使用什么方式join,这就涉及了Spark的几种join实现直接的关系,后续有时间再探讨这个

三、解决方案

根据以上简单分析,大致有以下三种解决方案

1、适当增加超时时间

spark.sql.broadcastTimeout=800

不过可能需要反复多调试几次,因为不知道多长时间合适,也就是常说的以时间换空间的方案

2、适当增加重试次数

spark.sql.broadcastMaxRetries=3

此种适合偶然现象,可能是因为集群中当时太多任务在运行,网络传输较为繁忙,数据输入较慢

3、加快处理速度(推荐)

这里通过优化调整参数来提升处理速度,开启MapJoin参数设置,在Map阶段完成join

(1)开启Mapjoin

hive.auto.convert.join = true;

 该参数开启了在map侧join,避免在reduce侧join,默认值true

(2)设置Mapjoin小表的阈值

hive.mapjoin.smalltable.filesize=50000000;

该参数决定在map侧join的具体标准,默认值25000000=25M,不超此值则开启map侧优化 ,具体多少合适需要根据自己表数据量的大小设置并反复调试

(3)开启worker节点缓存

hive.auto.convert.join.noconditionaltask = true;

该参数默认值为true ,用来来将一个小表变成hashtable然后作为分布式缓存文件分发到各个worker节点,进而实现在Map侧的连接优化机制

(4)设置worker节点缓存小表阈值

hive.auto.convert.join.noconditionaltask.size = 15000000;

该参数主要用来决定worker节点缓存的具体标准,默认值10000000=10M。

如果参与连接的n个表(或分区)中的n-1 的大小总和小于这个参数的值,即不超过此值,hive将启用小表在worker缓存,实现Map侧的连接优化机制。

具体多少合适需要根据自己表数据量的大小设置并反复调试


如有不正之处,还请留言指出,感谢批评!

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spark SQLSpark中的一个模块,用于处理结构化数据,通过执行SQL查询从而实现数据处理和分析任务。在使用Spark SQL时,可以通过调整核心参数来优化性能。 1. spark.sql.shuffle.partitions:这个参数指定了进行shuffle操作时的分区数。合理地设置这个参数可以提高整体性能。一般来说,当数据量较小时,设置为几倍于CPU核心数的值,当数据量较大时,可以根据具体情况进行调优。 2. spark.sql.autoBroadcastJoinThreshold:这个参数指定了进行Broadcast Join的阈值。Broadcast Join是指将小表广播到所有的Executor上,与大表进行Join操作,从而减少Shuffle的数据量。合理设置这个参数可以提高Join操作的性能。一般来说,当小表的大小小于等于10MB时,可以将这个参数设置为合适的值。 3. spark.sql.broadcastTimeout:这个参数指定了广播变量的超时时间。当Broadcast Join的阈值设置为正常值时,如果广播变量在超时时间内没有广播到Executor上,那么就会将Broadcast Join更改为Shuffle Join。根据网络情况和数据量大小合理设置这个参数可以提高性能。 除了上述参数,还可以通过设置一些其他的Spark SQL核心参数来优化性能,例如: - spark.sql.shuffle.compress:设置是否压缩shuffle的数据,默认为true,可以节省网络传输的数据量。 - spark.sql.inMemoryColumnarStorage.batchSize:设置内存列式存储的批处理大小,默认为10000,适当调整可以提高性能。 - spark.sql.adaptive.enabled:启用自适应执行优化,默认为false,可以根据实际情况开启。 综上所述,通过调整Spark SQL的核心参数可以提高性能,但是需要根据具体情况进行调优,找到最合适的参数值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值