分享

Hive的数据倾斜

 印度阿三17 2018-12-22

1、数据倾斜

1、什么是数据倾斜?
由于数据分布不均匀,造成数据大量的集中到一点造成数据热点。
2、Hadoop框架的特性

  • A、不怕数据大,怕数据倾斜
  • B、job数比较多的作业运行效率相对比较低,如子查询比较多
  • C、sum,count,max,min等聚集函数,通常不会有数据倾斜问题

3、主要表现
任务进度长时间维持在90%或者100%附近,发现只有少量的reduce子任务未完成,因为其处理的数据量和其他的reduce差异过大。

4、容易数据倾斜情况
操作:
在这里插入图片描述

  • A、group by 不和聚集函数搭配使用的时候
  • B、count(distinct),在数据量大的情况下,容易数据倾斜,因为count(distinct)是按 group by 字段分组,按 distinct 字段排序
  • C、 小表关联超大表 join

5、产生数据倾斜的原因

  • A:key 分布不均匀
  • B:业务数据本身的特性
  • C:建表考虑不周全
  • D:某些 HQL 语句本身就存在数据倾斜

6、业务场景
A:空值产生的数据倾斜
场景说明:在日志中,常会有信息丢失的问题,比如日志中的 user_id,如果取其中的
user_id 和用户表中的 user_id 相关联,就会碰到数据倾斜的问题。
解决方案 1:user_id 为空的不参与关联
select * from log a join user b on a.user_id is not null and a.user_id = b.user_id
union all
select * from log c where c.user_id is null;
解决方案 2:赋予空值新的 key 值
select * from log a left outer join user b on
case when a.user_id is null then concat(‘hive’,rand()) else a.user_id end = b.user_id

总结:方法 2 比方法 1 效率更好,不但 IO 少了,而且作业数也少了,
方案 1 中,log 表读了两次,jobs 肯定是 2,而方案 2 是 1。这个优化适合无效 id(比如-99,’’,null)产生的数据倾斜,把空值的 key 变成一个字符串加上一个随机数,就能把造成数据倾斜的数据分到不同的 reduce 上解决数据倾斜的问题。
改变之处:使本身为 null 的所有记录不会拥挤在同个 reduceTask 了,会由于有替代的随机字符串值,而分散到了多个 reduceTask 中了,由于 null 值关联上,处理后并不影响最终结果。

B:不同数据类型关联产生数据倾斜
场景说明:用户表中 user_id 字段为 int,log 表中 user_id 为既有 string 也有 int 的类型,当按照两个表的 user_id 进行 join 操作的时候,默认的 hash 操作会按照 int 类型的 id 进行分配,这样就会导致所有的 string 类型的 id 就被分到同一个 reducer 当中

解决方案:把数字类型 id 转换成 string 类型的 id
select * from user a left outer join log b on b.user_id = cast(a.user_id as string)

C:大小表关联查询产生数据倾斜
注意:使用map join解决小表关联大表造成的数据倾斜问题。这个方法使用的频率很高。

map join 概念:将其中做连接的小表(全量数据)分发到所有 MapTask 端进行 Join,从而避免了 reduceTask,前提要求是内存足以装下该全量数据

来源:http://www./content-4-95301.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多