在map和reduce两个阶段中,最容易出现数据倾斜的阶段是 reduce 阶段
因为从map 到 reduce 会经过shuffle阶段 ,shuffle 默认按照key 进行hash
如果相同的key太多 ,那么hash的结果 大量相同的key就会进入同一个reduce 导致数据倾斜
当然map阶段 也会出现数据倾斜:
map读取一个不支持切割格式文件、压缩文件的时候 并且文件超过一个数据块的大小(128M) 他只能分配一个map读取,就会在map阶段发生数据倾斜
本质来说:数据倾斜的原因:任务中处理大量相同key的数据,任务读取不可切割的大文件。
数据倾斜原因及解决办法:
1、空值引发数据倾斜:
a、过滤掉null数据
b、给随机值
2、不同数据类型引发数据倾斜:(join的时候)
a、统一数据类型
3、不可拆分大文件(GZIP)
a、避免使用分割的文件格式,尽量使用bzip和zip 等可分割的文件格式。
4、数据膨胀(分组聚合字段过多 with rollup)表示针对grouping sets/rollups/cubes这类多维聚合的操作
select a,b,c,count(1)from log group by a,b,c with rollup;
a、拆解语句
b、调整参数:hive.new.job.grouping.set.cardinality 默认30;自动控制作业的拆解
如果最后拆解的键组合大于该值,会启用新的任务去处理大于该值之外的组合。如果在处理数据时,某个分组聚合的列有较大的倾斜,可以适当调小该值
5、表连接(两表进行普通的repartition join时,如果表连接的键存在倾斜,那么在 Shuffle 阶段必然会引起数据倾斜)
a、mapjoin 在map阶段完成join ,避免shuffle (适用小表join大表场景)(注意加载进内存的小表的大小)
b、调整参数:hive.auto.convert.join=true 默认值为true,自动开启MAPJOIN优化。
hive.mapjoin.smalltable.filesize=2500000 默认值为2500000(25M),通过配置该属性来确定使用该优化的表的大小,如果表的大小小于此值就会被加载进内存中。
如果map端内存溢出 mapreduce.map.memory.mb 调节Map端内存的大小
6、无法解决数据量引发的数据倾斜:
如
select s_age,collect_list(s_score) list_score from student group by s_age;
collect_list:将分组中的某列转为一个数组返回。
1、reduce端内存溢出 调整 reduce 内存的大小 mapreduce.reduce.memory.mb
标签:解决办法,倾斜,map,reduce,HIVE,内存,join,数据 From: https://www.cnblogs.com/zhongxuzhi/p/16624352.html