数据倾斜如何分辨场景

目的

本文的重点是帮助大家分辨数据倾斜的场景。如果发现有不对的地方,请及时提出。

本质

数据倾斜的本质可以总结为四点:

  • join表大小不均匀:当两张表关联时,若表A有1000W条数据,而表B只有100条数据,那么计算资源会倾斜到处理表A上。
  • join条件不均匀:当表A和表B关联时,某些join条件的key匹配数量多于其他条件,例如A中的id存在重复值,而B中是随机值,这种情况下,某些join条件匹配的记录会多于其他条件。
  • groupby字段值分布不均匀:在进行聚合操作时,某些key在列中出现的次数太多,导致计算资源倾斜到处理这些热点key上。
  • 数据分布不均匀:文件块或分区不均匀,导致MapReduce按照分片或Spark按照文件数量进行计算,从而导致某些分区特别大,产生数据倾斜问题。

场景

下面几个场景都是比较独立的讨论,如果需求融合我会标黄:

数据量角度

  • 大小表:大小表关联基本上不会出问题,可以优先检查是否开启了MapJoin,并调整相关参数。也可以手动裁剪表,满足MapJoin的条件。另外,Hive Skew属性可以帮助检测倾斜问题,推荐尝试。
  • 大大表:对于大大表关联,可以尝试手动裁剪表,满足MapJoin的条件。不推荐使用SortMergeJoin,因为需要大量排序资源。BucketJoin可以加快速度,可以考虑采用hash分桶或范围分桶方式,但要注意分桶的合理性。
  • 多表:优化关联的先后顺序,来减少计算数据量,例如A左关联B后关联C,如果C中出现无法匹配到AB的记录,就会导致空关联。可以考虑调整为A关联(BCD的子查询)。这里提一嘴题外话除了数据量以外,对于多表关联,中间临时表的数据结构可能不好,导致关联过程中出现倾斜。可以在tmp级别调整分区,使用distribute by rank重新定义分区规则,改为随机分区。并且,多张表关联的文件块可能会影响Map阶段的性能,可以尝试平衡文件块

KEY角度

  • 预处理:可以通过采样或百分比采样,找到热点key。有三种方法可以实现采样,可以考虑是否可以废弃或单独处理热点key
  • 单独处理:单独提取倾斜的key进行关联,最后与没有倾斜的数据集进行UnionAll操作。也可以将倾斜的key单独广播到执行器,使用MapJoin避免Shuffle。还可以将倾斜的key进行分区或分桶,最后与没有倾斜的key进行UnionAll操作。
  • 同时处理:对全表的关联键进行加盐操作,给其加上随机前缀或新增一个哈希伪列,以提高并行度。在关联过程中,可以对on语句进行处理,例如使用case when a.id like "???"的方式。在进行GroupBy操作时,可以进行双端或多段聚合。还可以对A表和B表字段进行扩容或增加哈希伪列,适用于大量key倾斜,以空间换时间,但这种方法开销很大。

数据类型角度

  • Hive函数bug导致的倾斜,比如cast转换,遇到转换失败就会把所有value变成null,这样就会出现热点值,这种最好是考虑用其他函数替换或者做好数据排查。
  • Join key的问题,有的表的字段属性不同,比如表a是string类型,表b的是int类型,关联的时候就会发生大量的cast转换,这个时候也会产生数倾斜,这种最好在代码中进行cast转换或者预处理。

文件角度

  • 不可拆分的大文件,特别是Spark,如果遇到一个不可拆分的特别大文件,就会按照一个Map进行读取,考虑修改压缩格式或者其他分片策略。
  • ORC文件有特殊情况就是stripe信息过多,一个数据块如果是上游通过reduce合并的大量小文件生成的ORC文件,就有可能会因为读取ORC的大量头文件信息导致读取缓慢,这样最好就是选择合适的ORC策略或者更换文件类型。
  • 关联的表的数据分布不均匀,需要调整分区策略。
  • 关联的表的数据块大小不均匀,数据块参数调整或者是数据块重新分配。

引擎角度

  • MR多次落盘多个Job首尾呼应,有时候可以处理Spark处理不了的Job,但是资源消耗巨大,且MR作业吃了资源以后就不会改变,无法动态调整。
  • Spark作业基于内存,内存会是瓶颈,有时候可以观察集群资源或者Yarn的情况,但是Spark作业可以动态调整。

GROUP BY / JOIN

  • 处理方式不同
    • GroupBy倾斜,一般通过两阶段聚合,放粗粒度,以减少小数值的聚合,从而解决倾斜问题。
    • Join倾斜需要处理数据分布不均匀和Join条件不均匀两种问题,数据重新分区,Join条件调整。
  • 原因不同
    • GroupBy倾斜的原因包括:key值分布不均匀、数据中存在大量相同key值、数据中的key值存在大量异常值和空值、业务数据本身特性(例如某个分公司订单量大幅提升几十倍甚至几百倍,对该分公司的订单统计聚合时,容易发生数据倾斜)。
    • Join倾斜的场景包括:Join的两张表,其中有一张数据量很小;Join的两张表数据量都很大,表中存在大量空值;Join的两张表数据量都很大,由于数据本身分布不均匀导致倾斜。

总结

生产中最好先做好排查数据集大小、MapJoin、Skew参数,采样看一下是否有异常数据,包括垃圾数据和重复数据。

SQL写法中注意关联条件和子查询的过滤,避免数据空关联或者数据发散。

最后多习惯使用Explain查看执行计划,并且任务运行中多观察,到底是数据倾斜还是数据量实在过大,及时调整参数。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值