根本原因:数据过于集中。解决的基本思路:打散。
容易产生数据倾斜的几种情况:count distinct、group by key、Join。
- count distinct :
数据量小的时候无所谓,数据量大的情况下,由于COUNT DISTINCT操作需要用一个Reduce Task来完成,这一个Reduce需要处理的数据量太大,就会导致整个Job很难完成,一般COUNT DISTINCT使用先GROUP BY再COUNT的方式替换。
- group by key:
两种解决方法:第一种解决方案1)设置参数:这里有两个参数。i)开启map端聚合。
ii)有数据倾斜的时候开启负载均衡。开启了负载均衡以后,会生成两个mr,第一个mr会打散数据,也就是随机分发数据,进行局部聚合;第二个mr根据group by key的逻辑完成全局聚合。
2)手动优化sql:
两阶段聚合,加盐局部聚合,去盐全局聚合。(利用random构造辅助列,先group by key,random,进行局部聚合;再group by key完成全局聚合)。
- Join:
查看日志找到倾斜的key。
- 如果倾斜的key是脏数据,直接过滤掉;
- 增加reduce个数;
- 如果两个表join的时候,一个表为小表,可以用mapjoin做。
- 如果是两个大表join,并且倾斜的 key 有实际的意义,可以将它们单独抽取出来,对应的行单独存入临时表中,然后打上一个较小的随机数前缀(比如0~9),最后再进行聚合。
- 设置hive.optimize.skewjoin=true。