写在前面

        在任何大数据类的项目中,数据倾斜都是最棘手的性能问题,最能体现人的技术能力,最能体现RD(Research Developer,研发工程师)的技术水平。数据倾斜 = 性能杀手,如果没有丰富的经验,或者没有受过专业的技术培训,是很难解决数据倾斜问题的。 所以,数据倾斜解决方案,在整个项目中,都是非常非常核心、有含金量、有价值的。

数据倾斜产生后的现象:

        spark数据倾斜,有两种表现:  第一种,你的大部分的task,都执行的特别特别快,刷刷刷,就执行完了;剩下几个task,执行的特别特别慢,前面的task,一般1s可以执行完5个;最后发现1000个task,998,999 task,要执行1-2个小时才能执行完一个task。出现这种数据倾斜还算好的,因为虽然老牛拉破车一样,非常慢,但是至少还能跑。 第二种,运行的时候,其他task都刷刷刷执行完了,也没什么特别的问题;但是有的task,就是会突然间,啪,报了一个OOM,JVM Out Of Memory,内存溢出了,task failed,task lost,resubmitting task。反复执行几次都到了某个task就是跑不通,最后就挂掉。某个task就直接OOM,那么基本上也是因为数据倾斜了,task分配的数量实在是太大了!!!所以内存放不下,然后你的task每处理一条数据,还要创建大量的对象。内存爆掉了。出现数据倾斜了这种就不太好了,因为你的程序如果不去解决数据倾斜的问题,压根儿就跑不出来。作业都跑不完,还谈什么性能调优这些东西,省省吧你

数据倾斜解决方案:

        (一)最简单粗暴的方法----加资源,加并行度,注意RDD架构

        所谓“重剑无锋”,不管是调优还是数据倾斜,最朴素、最简谱、最直接、最有效、最简单的方案就是加资源!!!只要资源给到位,任何优化和倾斜都不是事儿。

        (二)过滤导致倾斜的key

        毕竟成本摆在那里,不会有哪个老板会甘心手下的小弟大手大脚的霍霍,所以,在没有足够的法力值来释放第一条的大招的时候,就要另辟蹊径,比如,看看导致倾斜的是否是需求必要的,问问老板倾斜的key能不能直接扔掉不要了

。如果可以,那么恭喜你,数据倾斜不攻自破;不过基本上会倾斜的数据都是不能舍弃的,毕竟大数据的价值有那么一条是因为“大”(Volume)......

        (三)聚合源数据

        spark作业的数据来源,90%的情况下,都是来自hdfs或者hive表。如果我们直接在生成hive表的hive etl中,对数据进行聚合。比如按key来分组,将key对应的所有的values,全部用一种特殊的格式,拼接到一个字符串里面去,那么就意味着,每个key就只对应一条数据。在spark中,就不需要再去执行groupByKey+map这种操作了。直接对每个key对应的values字符串,map操作,进行你需要的操作即可。key,values串。 spark中,可能对这个操作,就不需要执行shffule操作了,也就根本不可能导致数据倾斜。 或者是,对每个key在hive etl中进行聚合,对所有values聚合一下,不一定是拼接起来,可能是直接进行计算。reduceByKey,计算函数,应用在hive etl中,每个key的values。
        聚合源数据方案,还有一种做法,因为你可能没有办法对每个key,就聚合出来一条数据; 那么也可以做一个妥协,尽量去聚合,减少每个key对应的数量,也许聚合到比较粗的粒度之后,原先有10万数据量的key,现在只有1万数据量,也能减轻数据倾斜的现象和问题。
        聚合源数据这种解决方案,没法讲的太具体和仔细,只能给一个思路,但是,思路已经讲的非常清晰了。一般来说,大家只要有一些大数据(hive)经验,都是可以理解的,具体怎么去在hive etl中聚合和操作,就得根据你碰到数据倾斜问题的时候,你的spark作业的源hive表的具体情况,具体需求,具体功能,具体分析。

                                                             

                                                                                                                                                                                                      未完......