一、什么是数据倾斜
- 数据分布不均匀
- 本质上是MapReduce的数据倾斜
二、哪些操作容易造成数据倾斜
map端:一般不会。对应一个逻辑切片
reduce端:很容易产生数据倾斜
- 针对所有map输出结果
- 数据越大,reduce端的压力越大
- reduce端的并行度:节点个数*0.95。100个 * 0.95 (人少活多)
三、怎么判断程序发生了数据倾斜
在日志中reduce卡在某个进度:reduce = 80%, reduce = 80% ,reduce = 80%
原因:假设分了10个分区,则有10个reduce任务。9个已经跑完:进度 reduce = 90%。1个分区数据量特别大,reduceTask要执行很长时间。进度卡在 reduce = 90%,直到最后一个任务完成。
四、业务案例
淘宝数据:
- 女性 >> 男性
- 性别分区:处理男性数据的reduceTask很快就完成了,处理女性数据的reduceTask需要很长时间。
- 电信:流量使用:
- 地区进行分区
- 北京、内蒙古
- 北京的人数远大于内蒙古,必然产生数据倾斜
五、大数据编程
不怕数据量大,就怕数据倾斜。一旦数据倾斜,严重影响效率。
六、数据倾斜的原因
数据量大
归根结底就是分区
- map端key的设置
- key的设计要能做到每个分区数据量相对均匀
- hive转化mr时key的设置,key就是关联条件
七、哪些操作容易造成数据倾斜
1、join关联的时候有null值
表中需要的字段有大量的null值(不能去掉)。所有的null值reduce时会到同一个分区中。
null值特别多,会造成与null关联的分区数据特别多。必然产生数据倾斜。
如何解决:
- 关联时不让null进行关联,之后在把null值查出来,单独拼接
select
- 给null值加一个随机数
- null:null123 null:789 ...
- hive内置函数
2、关联的时候数据类型不统一
- int 类型和string类型进行关联。关联时候以小类型作为分区。这里int。
- string会到一个reduceTask中。如果数据量多,会造成数据倾斜。
如何ru'hrur解决jie'jjiejij:
cast(user.id as string)
3、大小表关联
join分为两种:
- map端join
- 效率高,并行度高,不容易产生数据倾斜。
- 擅长大小表关联。
- 设置map端join是否开启:set hive.auto.convert.join = true
- 设置map端join小表大小:set hive.mapjoin.smalltable.filesize = 25000000。只要小表大小不超过这个值。默认走map端join 。默认25MB
- 在进行关联操作的时候,两个表类似于mr程序中 FileInputFormat.addInputPath()
- 获取数据的长度,得出大表和小表的大小。如果两个表中最小表的大小不超25000000,默认会把小表放在缓存中。如果最小表大于设置的值,默认走reduce端的join。
- reduce端join
大表 join大表处理数据倾斜:
- 切分其中一个大表。一对多。切多的表。
- 26MB 1GB
- 默认 reduce端join
- 强制走map端join 。/*+mapjoin(a)*/ ,a表示需要加载到缓存中的表。只要小表大小内存可以承受。
/*+mapjoin(a)*/