最近一段时间主要在用Hive,前几天终于还是没有逃过经典的数据倾斜问题,备受煎熬,最后终于成功解决,这里记录一下心得。
直接上干货:解决数据倾斜问题,最大的难点在于知道为什么会倾斜!!!
一般会造成数据倾斜的情况无外乎在使用 group by 或者 distinct 或 join 等的情况中,由于数据分布不均所引起,尤其是Join的情况居多,我这次是使用group by的时候发生的数据倾斜,其实其他情况都可以用一样的处理方法。
情景复现:
一个很长很长的HQL语句,最终结果是把多个数据源的数据union 起来,然后写入目的表,执行脚本,HIVE划分成多个阶段,大概执行到后半部分的某个任务时,出现map 100%, reduce 99%的情况,然后一直是reduce 99%,直到一定时间之后,HIVE最终无法执行完成,报错。
分析过程:
日志平台是很好的帮助分析问题的工具,起码可以看到Map和Reduce阶段的进度,在我的例子中,最后只剩一个reducer在执行(实际是两个,因为集群会在只剩下一个reducer执行一段时间没有结束后,在另一个结点起相同的任务,两个结点有一个先跑完,就执行完成,但这两个阶段之间也会竞争资源,比如网络带宽等等),细看会发现,该reducer分配的数据量过多——典型的倾斜问题。
发现问题之后,我尝试了把多个数据源的数据分别单独执行,发现执行到其中一个数据源的时候,倾斜问题复现了,确认了一下这个数据源的数据量其实并没有比别的数据源大多少,说明不是数据量太多的问题(如果是因为数据量的话,还有可能报GC over limit之类的错误,这种错误可以通过设置hive参数,或者化整为零的思路解决)。
好,找到问题来源,根据group by的字段,写个简单的sql语句,就能看出来,每个执行结点大概能分到多少数据,一看就惊呆了,group by 的字段中,有一个全为null的组合,且为null的数据量太大,是其他组合的数十倍,而根据我写的语句,这