Hive数据倾斜
一、什么是数据倾斜:
数据倾斜就是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任务来避免数据倾斜的问题。
- 点赞
- 收藏
- 关注作者
评论(0)