1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > Hive中数据倾斜和小文件过多的解决方案

Hive中数据倾斜和小文件过多的解决方案

时间:2022-12-24 16:01:18

相关推荐

Hive中数据倾斜和小文件过多的解决方案

数据倾斜:

任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。因为其处理的数据量和其他reduce差异过大。

原因:某个reduce的数据输入量远远大于其他reduce数据的输入量

1)、key分布不均匀

2)、业务数据本身的特性

3)、建表时考虑不周

4)、某些SQL语句本身就有数据倾斜

解决方案:

(1)参数调节

set hive.map.aggr=true --在map端中会做部分聚集操作,效率更高但需要更多的内存,可以根据自己企业的资源情况来设置,set hive.groupby.skewindata=true--有数据倾斜的时候进行负载均衡 ,决定group by操作是否支持倾斜数据,其实说白了就相当于MR中的conbiner做了一次预聚合。注意:只能对单个字段聚合。控制生成两个MR Job,第一个MR Job Map的输出结果随机分配到reduce中减少某些key值条数过多某些key条数过小造成的数据倾斜问题。在第一个 MapReduce 中,map 的输出结果集合会随机分布到 reduce 中, 每个reduce 做部分聚合操作,并输出结果。这样处理的结果是,相同的 Group By Key 有可能分发到不同的reduce中,从而达到负载均衡的目的;第二个 MapReduce 任务再根据预处理的数据结果按照 Group By Key 分布到 reduce 中(这个过程可以保证相同的 Group By Key 分布到同一个 reduce 中),最后完成最终的聚合操作

(2) 可利用mapjoin进行优化(不适用所有场景)

小表在join左侧,大表在右侧,或使用mapjoin 将小表加载到内存中。然后再对比较大的表进行map操作。

join就发生在map操作的时候,这里的join并不会涉及reduce操作。map端join的优势就是在于没有shuffle,从而提升效率。

select /*+ MAPJOIN(a) */* from a join bwhere a.id = b.id;

(3) 熟悉数据的分布,优化sql的逻辑,找出数据倾斜的原因。

举例1:所有的空值都会被发送到同一个reduceTask去处理,造成数据倾斜。

空值过滤,不参与运算或进行赋值随机数。

if(id is null,cast(rand()*-100 as bigint),id)

举例2:加盐去盐操作,使数据分散

select count(distinct id) as num from table_name--优化1:select count(id) as num from (select id from table_name group by id) a;--优化2:select sum(tag_num) as numfrom(select tag,count(id) as tag_num--每个标记下的个数from(select id,CAST(RAND() * 100 AS BIGINT) tag --随机打上标记,标记为:0-100之间的整数from table_name group by id) tgroup by tag) t;--优化3:select sum(part_num) as numfrom(select substr(id, 1, 3) as id_part --截取id部分做维度,COUNT(DISTINCT substr(id, 4)) AS part_num --每个被截取的id下的个数from table_namegroup by substr(id, 1, 3)) t;

小文件过多

小文件的产生有三个地方,map输入,map输出,reduce输出,小文件过多也会影响hive的分析效率:

1、设置map输入的小文件合并

set mapred.max.split.size=256000000; //一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)set mapred.min.split.size.per.node=100000000;//一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并) set mapred.min.split.size.per.rack=100000000;//执行Map前进行小文件合并set hive.input.format=org.apache.hadoop.hive.bineHiveInputFormat;

2、设置map输出和reduce输出进行合并的相关参数:

//设置map端输出进行合并,默认为trueset hive.merge.mapfiles = true//设置reduce端输出进行合并,默认为falseset hive.merge.mapredfiles = true//设置合并文件的大小set hive.merge.size.per.task = 256*1000*1000//当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge。set hive.merge.smallfiles.avgsize=16000000

3、通过直接对系统文件进行操作来合并小文件

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。