Hive数据倾斜

举报
kala_1314 发表于 2019/01/18 14:20:07 2019/01/18
【摘要】 一、什么是数据倾斜:数据倾斜就是key的一些原因,导致分发到不同的reduce上,个别reduce任务特别重,以至于其他reduce都完成了,而这些个别的reduce仍然还需要一些时间才能完成。 发生数据倾斜的远因大概有: 1.输入的文件太多或者大小不一 2.hive的参数设置不合理 3.Hive SQL语句本身的缺陷 ...等等当然,肯定还有很多其他的一些原因会导致数据倾斜,这里只是列举一...

一、什么是数据倾斜:

数据倾斜就是key的一些原因,导致分发到不同的reduce上,个别reduce任务特别重,以至于其他reduce都完成了,而这些个别的reduce仍然还需要一些时间才能完成。 发生数据倾斜的远因大概有:

1.输入的文件太多或者大小不一

2.hive的参数设置不合理

3.Hive SQL语句本身的缺陷

...等等

当然,肯定还有很多其他的一些原因会导致数据倾斜,这里只是列举一些较为常见的并给出优化建议。


二、优化

在文件的大小上,如果小小文件太多,则会导致每个小文件被当成一个块,二样,每个小文件就会用一个map任务来完成,map的启动也是需要时间的,对与小文件来说,每个小文件都用一个map任务来完成是比较浪费资源的。在这种小文件特别多的情况下,在执行map任务前,就对文件进行处理,提前合并小文件,那么在map执行的时候就会减少一些map数。

文件再有一种情况是文件大小比较合理,文件数量也不多,但字段较少且记录较多。这种情况下,一个文件用一个map任务去执行可能也会话费比较多的时间,这种情况下可以考虑增加map数量。

在大表连接大表的时候,很有可能会由于空key的原因导致数据倾斜,在这种情况下,有两种方案: 第一种直接过滤掉,第二种就是把空值填上数据。一般来说,采用第二种方案,但在填充数值的时候,如果就用NVL直接将空值填充一个值也存在这不合理的地方。举个例子,如果数据量较大,空得太多,直接填充控制就会导致有很多的一样的key,这就会导致会被分发到一个任务上,同样也会导致数据倾斜。所以,在处理空值上需要填充不一样的数据。比如一个字符串加上一个随机数。就像这样:concat('字符串', rand())。就能把造成数据倾斜的 数据分到不同的 reduce 上解决数据倾斜的问题。

在不同数据类型关联也非常容易产生数据倾斜。在进行关联的时候,有可能会出现关联字段因为数据类型的不同,导致不同的数据类型的字段分配到同一个任务中造成数据倾斜。在这样的情况下,在执行任务钱就可以提前将数据类型转为一致。


针对group by的一些优化。group by 会将group by的字段聚合在一起并且会把这些相同的字段发到同一个reduce端,就造成了数据倾斜。但其实,并不是所有的聚合操作都需要在reduce端完成,很多聚合操作可以在map端进行部分聚合,最后在reduce端得出结果。首先要开启map端聚合:设置 hive.map.aggr=true(默认为true),但如果每条数据基本不同的情况下,聚合也没什么意义,这里也可以通过 hive.groupby.mapaggr.checkinterval 设置map端进行聚合操作的数量,默认100000。 还可以把 hive.groupby.skewindata 设置为 true,这样会生成两个MapReduce任务(第一个MapReduce任务Map的输出结果随机分配到reduce做预汇总,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce中,从而达到负载均衡的目的;第二个 MapReduce任务再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中,这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中,最后完成最终的聚合操作),通过两个MapReduce任务来避免数据倾斜的问题。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。