Hive 表关联查询,如何解决数据倾斜的问题?
1)倾斜原因:
map 输出数据按 key Hash 的分配到 reduce 中,由于 key 分布不均匀、业务数据本身的特、建表时考虑不周、等原因造成的 reduce 上的 数据量差异过大。
(1)key 分布不均匀;
(2)业务数据本身的特性;
(3)建表时考虑不周;
(4)某些 SQL 语句本身就有数据倾斜; 如何避免:对于 key 为空产生的数据倾斜,可以对其赋予一个随机值。
(2)解决方案
(1)参数调节: hive.map.aggr = true hive.groupby.skewindata=true 有数据倾斜的时候进行负载均衡,当选项设定位 true,生成的查询计划会有两 个 MR Job。第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的; 第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中), 最后完成最终的聚合操作。
(2)SQL 语句调节:
① 选用 join key 分布最均匀的表作为驱动表。做好列裁剪和 filter 操作,以 达到两表做 join 的时候,数据量相对变小的效果。
② 大小表 Join: 使用 map join 让小的维度表(1000 条以下的记录条数)先进内存。在 map 端完成 reduce。
③ 大表 Join 大表: 把空值的 key 变成一个字符串加上随机数,把倾斜的数据分到不同的 reduce 上,由于 null 值关联不上,处理后并不影响最终结果。
④ count distinct 大量相同特殊值: count distinct 时,将值为空的情况单独处理,如果是计算 count distinct, 可以不用处理,直接过滤,在最后结果中加 1。如果还有其他计算,需要进行 group by,可以先将值为空的记录单独处理,再和其他计算结果进行 union。