spark参数调优

目录

    • 1 小文件优化
    • 2、数据量优化
      • 2.1 谓词下推-输入数据
      • 2.2 膨胀数据优化-中间数据
    • 3、计算逻辑优化
      • 3.1 创建临时表
      • 3.2 join优化
      • 3.3 并行度优化
    • 4、数据倾斜优化

1 小文件优化

添加链接描述

2、数据量优化

2.1 谓词下推-输入数据

谓词下推就是将查询的过滤条件尽可能下沉到数据源,减少对无关数据的读入。Spark在生成执行计划时会进行谓词下推的优化,对于内连接而言,过滤条件写在join中或者join后并没有差异,但是对于外连接,会存在不能谓词下推的情况。
参考:谓词下推介绍

2.2 膨胀数据优化-中间数据

COUNT DISTINCT实现原理、spark sql多维分析优化
中间数据量指的是Spark任务在计算过程中产生的数据量,也就是RDD的数据量。常见的两种导致数据膨胀的逻辑便是count(distinct )和grouping sets( )。数据膨胀是空间换时间的一种方式,适宜数据量小的情况。

** 1. count(distinct):** 对于count(distinct)带来的数据膨胀,我们可以采用size+collect_set的方法来进行优化。size(collect_set())实际上是依赖集合的数据结构进行去重,因此不会引起数据膨胀。

-- 替换前
count(distinct sku_id) as sku_num,
-- 替换后
size(collect_set(sku_id)) as sku_num,

**2.grouping sets:**建议在做grouping sets,把数据提前汇总一次,仅保留需要的维度和指标,尽量做到输入最少的数据。

  • 上述两种场景可以采用拆分的方式来进行优化,即把一段count(distinct)拆成多段count(distinct)union all起来,或把一个grouping sets为多个grouping sets。虽然没有减少总体上中间处理的数据量,但是对单个task来说,计算压力会小很多。
select count(distinct a) as a_num,
       count(distinct b) as b_num,
       count(distinct c) as c_num,
       count(distinct d) as d_num,
       count(distinct e) as e_num,
       count(distinct f) as f_num
  from result 
  -- 拆分后
select count(distinct a) as a_num,
       count(distinct b) as b_num,
       count(distinct c) as c_num,
       null as d_num,
       null as e_num,
       null as f_num
  from result
union all select null as a_num,
       null as b_num,
       null as c_num,
       count(distinct d) as d_num,
       count(distinct e) as e_num,
       count(distinct f) as f_num
  from result

3、计算逻辑优化

3.1 创建临时表

如果我们在任务中多次使用该子查询,就会导致子查询被重复执行多次。
解决方法就是将表cache到内存(数据量较小)或创建临时表(数据量较大)。在分区任务创建临时表时,建议临时表名带上时间变量的参数(如:‘tmp_table’+‘$now.datekey’),避免并行重导时产生表名冲突。

3.2 join优化

Broadcast Hash Join原理:先将小表拉到driver端,再把小表的数据广播到Spark的所有Executor端,然后在每个Executor端进行小表和大表的join,实现了map端的join操作,从而避免了shuffle。我们可以通过以下两种方式来实现Broadcast Hash Join。

  • 参数调整:当小表的数据量小于 spark.sql.autoBroadcastJoinThreshold
    参数时便会自动进行广播,该参数的默认值为10MB。需要注意的是,我们的表大部分为ORC压缩格式,解压后的数据量增长数倍。
  • 强制广播:我们还可以使用hint的方式来强制Spark在运行时采用Broadcast Hash Join做数据关联,即:
    /+MAPJOIN(表别名)/
select /*+ MAPJOIN(b) */
	a.key,
	b.value
from res1 a
join res2 b
on a.key=b.key

3.3 并行度优化

某个stage执行时间很长,但是stage内并行的task数量很少。
1、读文件优化
仅读文件优化,调整读文件并行度参数。

set spark.hadoop.hive.exec.orc.split.strategy=ETL;
set spark.hadoop.mapreduce.input.fileinputformat.split.maxsize=100663296; -- 调小该数值
set spark.hadoop.mapreduce.input.fileinputformat.split.minsize=100663296;

如果读文件后还有其他操作,导致执行时间长,那么在读文件后进行重分区,将读文件和其他RDD操作划分为不同stage。

1)全局增加分区
set spark.sql.adaptive.shuffle.targetPostShuffleInputSize=5592405;(数值需根据任务情况自行调整,减少该数值)
(全局增加分区,可能带来不必要的资源开销,也有可能造成小文件过多的情况)
前提是设置set spark.sql.shuffle.partition=true

2)局部增加分区(建议)
在shuffle前增加 distribute by语句,进行强制分区

参数解释:
spark.sql.adaptive.enabled:是否开启调整partition功能,如果开启,spark.sql.shuffle.partitions设置的partition可能会被合并到一个reducer里运行。平台默认开启,同时强烈建议开启。理由:更好利用单个executor的性能,还能缓解小文件问题。

spark.sql.adaptive.shuffle.targetPostShuffleInputSize:和spark.sql.adaptive.enabled配合使用,当开启调整partition功能后,当mapper端两个partition的数据合并后数据量小于targetPostShuffleInputSize时,Spark会将两个partition进行合并到一个reducer端进行处理。平台默认为67108864(64M),用户可根据自身作业的情况酌情调整该值。当调大该值时,一个reduce端task处理的数据量变大,最终产出的数据,存到HDFS上的文件也变大。当调小该值时,相反。

2、计算优化-单task处理任务较多
set spark.sql.adaptive.shuffle.targetPostShuffleInputSize=5592405;(数值需根据任务情况自行调整,减少该数值;全局增加分区,可能带来不必要的资源开销,也有可能造成小文件过多的情况)
3、写文件优化
增加写文件并行度:如distribute by dt, abs(hash(id) % 10) 。尽可能不要用rand函数。

4、数据倾斜优化

现象:绝大多数task执行得都非常快,但个别task执行极慢
原因:shuffle时某些key的数量特别大,导致数据分配不均,少量的task处理了绝大部分数据量
优化方法:转化map join、过滤无效极值、随机膨胀等
数据倾斜问题

你可能感兴趣的:(spark,ajax,javascript)