HiveSQL、SparkSQL数据倾斜解决思路及示例

数据倾斜常见特征

  1. 同一个stage的task中,有个别的task执行时间明显比其他的要长得多,整体stage临近结束但一直卡着很长一段时间。
  2. 整体任务数据量不大,经常OOM(内存溢出)。即使通过参数增大了内存,已经比一般的任务要大得多了,而且减少了每个task处理的数据量,依然无济于事。

起因

shuffle阶段key的分布不均,单个task读取数据过多,导致执行时间变长,甚至撑爆内存。
HiveSQL或SparkSQL会引起shuffle的操作:reduce join、group by

  • reduce join操作的key:关联的字段(on子句上的字段)
  • group by操作的key:聚合列(group by子句上的字段)
    注:Hive on Spark和Spark SQL是两种不同的东西,请注意区分。

解决原则

  1. 二选一:
    1.1 消除数据倾斜:只有一种可能:reduce join改map join
    1.2 缓解数据倾斜:让每个key处理的平均数据量更均匀
  2. 不过度优化:没有出现性能问题就不优化。优化后务必与原来的方案进行比较。
  3. 当前新版本的SQL引擎(Hive3.0、Spark2.X),大部分已经内置优化了group by,大多数情况下不需要做优化。

解决数据倾斜之后可能出现的现象

  1. 可能有更多的数据操作,产生更多的IO(map join、broadcast join这类操作基本忽略不计)
  2. 或许会增加处理时长,但单个task处理数据量上限可下调,任务总体资源消耗得到优化,运行状态也会更稳定。

解决思路

join
1. 存在一张小表

若有一张表比较小,通过参数把SQL转为map join(HiveSQL)或者broadcast join(SparkSQL)。
这两个优化操作在对应的引擎里都是默认开启的。

  1. SparkSQL broadcast join默认判断标准是表小于10MB。(参数:
    spark.sql.autoBroadcastJoinThreshold,设置为-1时关闭broadcast join)
    开关为:
  2. HiveSQL map join的默认判断标准是表小于25M。(参数:hive.mapjoin.smalltable.filesize,开关:hive.auto.convert.join
    参考资料:https://blog.csdn.net/qq_28069577/article/details/99288640
2. 不存在小表,表都比较大

表都比较大,不适合map join和broadcast join。部分云服务商的SQL工具会有参数可以进行优化,自建集群大部分情况下要借助随机数改写SQL以缓解数据倾斜。
根据异常值是否需要保留展示、异常值的数量多少,处理方式略有不同。

group by

当前一些版本SQL引擎(Hive3.0以上、Spark2.X),group by的优化做得已经很好了,基本不怎么需要额外优化,以下可当作是优化原理解析。

没有count(distinct)
  1. 随机数双重聚合
    给原group by的列加上cast(rand() * N as int)进行第一次聚合,然后对子查询再做一次聚合
  2. 加参数:set hive.groupby.skewindata=true;

两种方法原理相近,都是通过随机数把key尽可能均匀分摊到不同的分区中,通过多次的操作完成聚合。

有count(distinct)
  1. 在hive3.0及以上版本,设置参数:set hive.optimize.countdistinct=true;。此为默认设置。
    注:set hive.groupby.skewindata=true;时不支持multi distinct,且在hive1.2.0以前的版本在混有single distinct的场景下会导致数据统计异常,这种场景下请勿设置。
  2. Spark2.X版本(疑似从2.0开始)能够自动优化。
  3. 在其他的旧版本,有可能没有默认参数解决数据倾斜。这个时候就需要借助hive和spark的优化思路做出手工调整。详见案例。
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值