核心问题:key过多,读取、计算或是join时导致数据倾斜
map端长尾
第一种情况问题描述:上游表文件的大小特别不均匀,而且小文件特别多,导致当前表Map端读取的数据分布不均匀,引起长尾
第一种情况解决方案:读取的时候合并小文件,尽量做到读取文件大小差不多
第二种情况问题描述:Map端做聚合时,就是combine操作的时候读取文件的某个值特别多而引起长尾
第二种情况解决方案:用distribute by rand() 来打乱数据分布,访问读取某一个key的数据过多
reduce端长尾
第一种情况问题描述:key中存在大量的null值或是非正常字符值
第一种情况解决方案:值过滤,或是将key值随机化生成
第二种情况问题描述:热点key值过大,导致倾斜
第二种情况解决方案:
- 热点可以单独计算,然后合并到主链路中
- 加盐操作,例如group by key
第三种情况问题描述:count distinct造成的长尾
第三种情况解决方案:用group by先过滤去重,可以并行操作(上述是串行执行的)
join端长尾
第一种情况问题描述:join的某路输入比较小,可以采用mapjoin,避免分发产生倾斜
第一种情况解决方案:直接走map join,没有任何的shuffle过程,从而提高效率
第二种情况问题描述:join的两路数据量都很大
第二种情况解决方案:
- join侧数据,提前distinct需要保留的字段,避免热点
- 取出热点数据单独计算,然后在合并到主链路中
- 设置参数skew join hint来避免热值倾斜
- 避免使用full join