Hive数据倾斜方案

数据倾斜:
数据倾斜通常发生在 MapReduce 框架中,通俗理解就是在整个计算过程中,大量相同的 key 被分配到同一个任务上,导致大部分任务空闲,个别任务一直运算,使得计算效率很低。

MapReduce 执行原理:

  • Map 任务
  • MapReduce 读取 HDFS 中的文件并进行切割,将每行解析成一个
    Map 任务将上一步生成的 值转换成新的 ,并将结果写入到环形缓冲内存中(溢出的部分写入磁盘)。
    Map 任务将不同分区中的数据进行排序、分组,将相同的 k 放入同一个集合中(溢出的部分写入磁盘)。
    Map 对分组后的任务进行归约。

  • Reduce 任务
  • Reduce 任务先处理多个 Map 任务的输出结果,再根据分区将其分配到不同的 Reduce 节点上(shuffle)。
    Reduce 对多个 Map 的输出结果进行合并、排序、计算,重新生成新的 值。
    Reduce 将上一步生成的 值写入到 HDFS 中,生成文件。

解决方案:
日常工作中产生的数据倾斜多产生于 Reduce 阶段,其原因在于没有考虑到某种 key 值数据过多而导致的。
而最容易产生数据倾斜的两个场景分别是 Join 和 Count Distinct,解决该问题首先需要调整系统参数,进行负载均衡处理;之后再对相应的 SQL 进行优化。
  • 设置参数
  • set hive.map.aggr = true; set hive.groupby.skewindata = true;
    将上述两个参数设置为 true 后,MapReduce 进程会生成两个额外的 MR Job,这两个任务的主要操作如下:

    • MR Job 中的 Map 输出结果集合首先会随机分配到 Reduce 中,然后每个 Reduce 做局部聚合操作并输出结果(相同的 Group By Key 可能会被送到不同的 Reduce Job 中)。
    • MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(相同的 Group By Key 会被送到相同的 Reduce Job 中),最后完成聚合操作。

  • SQL 优化
总结:
  • 如果任务长时间卡顿在 99%,那大概率发生了数据倾斜。
  • 小表关联大表,需要先看能够使用子查询,再看能否使用 Mapjoin。
  • Join 操作注意关联字段不要出现大量的重复值或空值。
  • Count(Distinct id) 去重统计慎重使用,尽量通过其他方式替换。