hive 数据倾斜

源地址:http://www.cnblogs.com/xuxm2007/archive/2011/09/01/2161929.html

hadoop job解决大数据量关联时数据倾斜的一种办法

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

用hadoop程序进行数据关联时,常碰到数据倾斜的情况,这里提供一种解决方法。

(1)设置一个hash份数N,用来对条数众多的key进行打散。

(2)对有多条重复key的那份数据进行处理:从1到N将数字加在key后面作为新key,如果需要和另一份数据关联的话,则要重写比较类和分发类(方法如上篇《hadoop job解决大数据量关联的一种方法》)。如此实现多条key的平均分发。

int iNum = iNum % iHashNum;

String strKey = key + CTRLC + String.valueOf(iNum) + CTRLB + “B”;

(3)上一步之后,key被平均分散到很多不同的reduce节点。如果需要和其他数据关联,为了保证每个reduce节点上都有关联的key,对另一份单一key的数据进行处理:循环的从1到N将数字加在key后面作为新key

for(int i = 0; i < iHashNum; ++i){

String strKey =key + CTRLC + String.valueOf(i) ;

output.collect(new Text(strKey), new Text(strValues));}

以此解决数据倾斜的问题,经试验大大减少了程序的运行时间。但此方法会成倍的增加其中一份数据的数据量,以增加shuffle数据量为代价,所以使用此方法时,要多次试验,取一个最佳的hash份数值。

======================================

用上述的方法虽然可以解决数据倾斜,但是当关联的数据量巨大时,如果成倍的增长某份数据,会导致reduce shuffle的数据量变的巨大,得不偿失,从而无法解决运行时间慢的问题。

有一个新的办法可以解决 成倍增长数据 的缺陷:

在两份数据中找共同点,比如两份数据里除了关联的字段以外,还有另外相同含义的字段,如果这个字段在所有log中的重复率比较小,则可以用这个字段作为计算hash的值,如果是数字,可以用来模hash的份数,如果是字符可以用hashcode来模hash的份数(当然数字为了避免落到同一个reduce上的数据过多,也可以用hashcode),这样如果这个字段的值分布足够平均的话,就可以解决上述的问题。-


源地址:http://blog.sina.com.cn/s/blog_7ffad74901011s6c.html

关于hive中的数据倾斜,淘宝的博客上有篇很好的文章: http://www.tbdata.org/archives/2109


症状和原因:
  • 操作:join,group by,count distinct 
  • 原因:key分布不均匀,人为的建表疏忽,业务数据特点。
  • 症状:任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成;查看未完成的子任务,可以看到本地读写数据量积累非常大,通常超过10GB可以认定为发生数据倾斜。
  • 倾斜度:平均记录数超过50w且最大记录数是超过平均记录数的4倍;最长时长比平均时长超过4分钟,且最大时长超过平均时长的2倍。
我遇到的问题:
select * from a join b;
1. a表1000多万,b表不到2亿,用mapjoin显然不行;
2. 设置参数 set  hive.groupby.skewindata=true,不起作用;
3. 由于关连键为手机号,自认为业务数据上不存在数据倾斜;

后来通过查看每个表里面关联键的分布,才发现两个表里面都存在空串'',而且严重倾斜,大表里面的空串数量有400多万。
将两个表的空串过滤后再进行关联,job时间由原来的40多分钟减少到2分钟。

总结:
  1. 数据倾斜的原因就那么几种,逐一排查;
  2. 细心,动手,不能光凭感觉来判定;
  3. 判定某一个表的key是否存在数据倾斜,就是group by key,取top N来看;

附:数据倾斜常用解决方法:

1.  万能膏药:hive.groupby.skewindata=true
2. 大小表关联:将key相对分散,并且数据量小的表放在join的左边,这样可以有效减少内存溢出错误发生的几率;再进一步,可以使用map join让小的维度表(1000条以下的记录条数)先迚内存。在map端完成reduce.
3. 大表和大表关联:把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null值关联不上,处理后并不影响最终结果。
4.  count distinct大量相同特殊值:count distinct时,将值为空的情况单独处理,如果是计算count distinct,可以不用处理,直接过滤,在最后结果中加1。如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行union。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值