Hive数据倾斜

map/reduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长,这是因为某一个key的条数比其他key多很多(有时是百倍或者千倍之多),这条key所在的reduce节点所处理的数据量比其他节点就大很多,从而导致某几个节点迟迟运行不完,此称之为数据倾斜。

1.万能膏药: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. 大小表关联:
可以使用Map Join让小的维度表(1000条以下的记录条数)先进内存。在map端完成reduce.

3. 大表和大表关联:
把空值NULL的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null值关联不上,处理后并不影响最终结果。例如Demo1.空值数据倾斜

4. count distinct大量相同特殊值:
count distinct时,将值为空的情况单独处理。如果是计算count distinct,可以不用处理,直接过滤,在最后结果中加1。如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行union。

Demo1.空值数据倾斜
场景:如日志中,常会有信息丢失的问题,比如全网日志中的user_id,如果取其中的user_id和bmw_users关联,会碰到数据倾斜的问题。
解决方法1: user_id为空的不参与关联

Select * From log a
 Join bmw_users b On a.user_id is not null And a.user_id = b.user_id
 Union allSelect * from log a where a.user_id is null;

解决方法2 :赋予空值新的key值

Select * from log a
  left outer Join bmw_users b
on case when a.user_id is null then concat(‘dp_hive’,rand())   else a.user_id end = b.user_id; 

结论:方法2比方法1效率更好,不但io少了,而且作业数也少了。
方法1的log读取两次,jobs是2。方法2的job数是1。这个优化适合无效id(比如-99,’’,null等)产生的倾斜问题。
把空值的key变成一个字符串加上随机数,就能把倾斜的数据分到不同的reduce上 ,解决数据倾斜问题。

Demo2.不同数据类型关联产生数据倾斜
场景:一张表s8的日志,每个商品一条记录,要和商品表关联。但关联却碰到倾斜的问题,s8的日志中有字符串商品id,也有数字的商品id,类型是string的,但商品中的数字id是bigint的。
问题原因:把s8的商品id转成数字id做hash来分配reduce,所以字符串id的s8日志,都到一个reduce上了,解决的方法验证了这个猜测。
解决方法:把数字类型转换成字符串类型

Select * from s8_log a
 Left outer join r_auction_auctions b
  On a.auction_id = cast(b.auction_id as string);

Demo3.大表Join的数据偏斜
MapReduce编程模型下开发代码需要考虑数据偏斜的问题,Hive代码也是一样。数据偏斜的原因包括以下两点:
  1. Map输出key数量极少,导致reduce端退化为单机作业。
  2. Map输出key分布不均,少量key对应大量value,导致reduce端单机瓶颈。
Hive中我们使用MapJoin解决数据偏斜的问题,即将其中的某个小表(全量)分发到所有Map端的内存进行Join,从而避免了reduce。这要求分发的表可以被全量载入内存。
极限情况下,Join两边的表都是大表,就无法使用MapJoin。这种问题最为棘手,目前已知的解决思路有两种:
1. 如果是上述情况1,考虑先对Join中的一个表去重,以此结果过滤无用信息。
  这样一般会将其中一个大表转化为小表,再使用MapJoin 。一个实例是广告投放效果分析,
  例如将广告投放者信息表i中的信息填充到广告曝光日志表w中,使用投放者id关联。因为实际广告投放者数量很少(但是投放者信息表i很大),因此可以考虑先在w表中去重查询所有实际广告投放者id列表,以此Join过滤表i,这一结果必然是一个小表,就可以使用MapJoin。

select /*+mapjoin(x)*/* from log a left outer join (
  select /*+mapjoin(c)*/d.*
  from ( select distinct user_id from log ) c
  join users d on c.user_id = d.user_id
) x on a.user_id = b.user_id;

2. 如果是上述情况2,考虑切分Join中的一个表为多片,以便将切片全部载入内存,然后采用多次MapJoin得到结果。
一个实例是商品浏览日志分析,例如将商品信息表i中的信息填充到商品浏览日志表w中,使用商品id关联。但是某些热卖商品浏览量很大,造成数据偏斜。例如,以下语句实现了一个inner join逻辑,将商品信息表拆分成2个表:

select * from(
  select w.id, w.time, w.amount, i1.name, i1.loc, i1.cat
    from w left outer join i sampletable(1 out of 2 on id) i1)
union all(
  select w.id, w.time, w.amount, i2.name, i2.loc, i2.cat
    from w left outer join i sampletable(1 out of 2 on id) i2);
时间: 2024-10-16 11:14:32

Hive数据倾斜的相关文章

HIVE数据倾斜问题

HIVE数据倾斜问题问题状态: 未解决 背景:HDFS对文件进行了压缩,而且不添加索引.主要用HIVE进行开发. 发现的现象:sqoop从Mysql导入数据,根据ID进行平均分割,但是ID分部及其不均匀(我也不知道业务系统怎么搞得).所以导致reduce出来的文件大小严重不均匀,就是所谓的数据倾斜. 导致的问题:写HQL从该表中读取数据,发现整个job很慢.后来我查日志发现,有几个map读取数据非常慢,1G的文件大概需要1个多小时才能读取完毕. 问题分析: 由于hadoop对文件进行了lzo格式

Hive数据倾斜总结

倾斜的原因: 使map的输出数据更均匀的分布到reduce中去,是我们的最终目标.由于Hash算法的局限性,按key Hash会或多或少的造成数据倾斜.大量经验表明数据倾斜的原因是人为的建表疏忽或业务逻辑可以规避的. 解决思路: Hive的执行是分阶段的,map处理数据量的差异取决于上一个stage的reduce输出,所以如何将数据均匀的分配到各个reduce中,就是解决数据倾斜的根本所在 具体办法: 内存优化和I/O优化: 驱动表:使用大表做驱动表,以防止内存溢出:Join最右边的表是驱动表:

Hive数据倾斜的原因及主要解决方法

数据倾斜产生的原因 数据倾斜的原因很大部分是join倾斜和聚合倾斜两大类 Hive倾斜之group by聚合倾斜 原因: 分组的维度过少,每个维度的值过多,导致处理某值的reduce耗时很久: 对一些类型统计的时候某种类型的数据量特别多,其他的数据类型特别少.当按照类型进行group by的时候,会将相同的group by字段的reduce任务需要的数据拉取到同一个节点进行聚合,而当其中每一组的数据量过大时,会出现其他组的计算已经完成而这个reduce还没有计算完成,其他的节点一直等待这个节点的

16、Hive数据倾斜与解决方案

数据倾斜 1.什么是数据倾斜 由于数据分布不均匀,造成数据大量的集中到一点,造成数据热点 2.数据倾斜的现象 在执行任务的时候,任务进度长时间维持在99%左右,查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成.因为其处理的数据量和其他reduce差异过大. 单一reduce的记录数与平均记录数差异过大,通常可能达到3倍甚至更多.最长时长远大于平均时长. 3.数据倾斜的情况 4.数据倾斜的原因 1).key分布不均匀 2).业务数据本身的特性 3).建表时考虑不周 4).某些S

[Hive]Hive数据倾斜(大表join大表)

业务背景 用户轨迹工程的性能瓶颈一直是etract_track_info,其中耗时大户主要在于trackinfo与pm_info进行左关联的环节,trackinfo与pm_info两张表均为GB级别,左关联代码块如下: from trackinfo a left outer join pm_info b on (a.ext_field7 = b.id) 使用以上代码块需要耗时1.5小时. 优化流程 第一次优化 考虑到pm_info表的id是bigint类型,trackinfo表的ext_fiel

浅析 Hadoop 中的数据倾斜

转自:http://my.oschina.net/leejun2005/blog/100922 最近几次被问到关于数据倾斜的问题,这里找了些资料也结合一些自己的理解. 在并行计算中我们总希望分配的每一个task 都能以差不多的粒度来切分并且完成时间相差不大,但是集群中可能硬件不同,应用的类型不同和切分的数据大小不一致总会导致有部分任务极大的拖慢了整个任务的完成时间,硬件不同就不说了,应用的类型不同其中就比如page rank 或者data mining 里面一些计算,它的每条记录消耗的成本不太一

hive大数据倾斜总结

在做Shuffle阶段的优化过程中,遇到了数据倾斜的问题,造成了对一些情况下优化效果不明显.主要是因为在Job完成后的所得到的 Counters是整个Job的总和,优化是基于这些Counters得出的平均值,而由于数据倾斜的原因造成map处理数据量的差异过大,使得这些平均 值能代表的价值降低.Hive的执行是分阶段的,map处理数据量的差异取决于上一个stage的reduce输出,所以如何将数据均匀的分配到各个 reduce中,就是解决数据倾斜的根本所在.规避错误来更好的运行比解决错误更高效.在

Hive语法层面优化之一数据倾斜介绍

数据倾斜:数据分布不均匀,造成数据大量的集中到一点,造成数据热点: 由于数据并不是平均分配的,会导致各个节点上处理的数据量是不均衡的,所以数据倾斜是无法避免的: 造成数据倾斜的最根本原因:key分发不均匀造成的: 常见的数据倾斜的症状 1)  Map阶段快,reduce阶段非常慢: 2)  某些map很快,某些map很慢: 3)  某些reduce很快,某些reduce很慢: 4)  任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成,

Hive语法层面优化之四count(distinct)引起的数据倾斜

当该字段存在大量值为null或空的记录,容易发生数据倾斜: 解决思路: count distinct时,将值为空的情况单独处理,如果是计算count distinct,可以不用处理,直接过滤,在最后结果中加1: 如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行union. 案例: select count(distinct end_user_id) as user_num from trackinfo; 调整为: select cast(count(