• Spark项目故障思路整理总结


    Spark项目总结

    数据倾斜解决方案

    数据倾斜解决方案之原理以及现象分析

    1.数据倾斜的原理

    在执行Shuffle操作的时候,大家都知道,我们之前讲解过Shuffle的原理。是按照Key,来进行values的数据的输出,拉取和聚合的。同一个key的values,
    一定是分配到一个reduce task进行处理的。多个key对应的values,总共是90万。但是问题是,可能某个key对应了88万数据,key-88万values,分配到一个
    task上面去执行。另外两个各分配到了1万数据,可能是数百个key,对应的1万条数据。那么可能1万条数据,需要10分钟计算完毕;,第一个和第二个可能同时
    在10分钟内都运行完了,第三个task有88万,就需要 14.5小时处理完

    2.数据倾斜的现象

    发生数据清洗以后的现象:

    1.大部分的task,都指向的特别特别的快(你要用clien模式,standalone client,yarn client,本地机器主要指向spark-submit脚本,就会开始打印log),task 175finished,
    剩下几个task,一般1s可以指向完5个;最后发现1000个task,999,998个task,要执行1个小时,2个小时才能执行完1个task.这样就出现了数据倾斜。
    2.运行的时候,其他task都执行完了,也没有什么特别的问题。但是有的task,就是会突然件,啪,报一个OOM,JVM Out Of Memory,内存溢出了,task failed,task lost,
    resubmitting task.反复执行几次都到了某个task就是跑不通,最后就挂掉。某个task就直接OOM,JVM Out Of Memory 那么基本上也是因为数据倾斜,task分配的数量实战是太大了
    所以内存放不下,然后task每处理一条数据,还要创建大量的对象,内存就爆掉了

    3.数据倾斜的产生原因与定位

    定位原因与出现问题的位置:
    根据log去定位
    出现数据倾斜的原因,基本只可能是因为发生了shuffle操作,在shuffle的过程中,出现了数据倾斜的问题。因为某个,或者某些key对应的数据,远远的高于其他的key。
    1、你在自己的程序里面找找,哪些地方用了会产生shuffle的算子,groupByKey、countByKey、reduceByKey、join
    2、看log
    log一般会报是在你的哪一行代码,导致了OOM异常;或者呢,看log,看看是执行到了第几个stage!!!
    我们这里不会去剖析stage的划分算法,(如果之前不了解,但是想要了解,建议先学习北风网的《Spark从入门到精通》),spark代码,是怎么划分成一个一个的stage的。哪一个stage,
    task特别慢,就能够自己用肉眼去对你的spark代码进行stage的划分,就能够通过stage定位到你的代码,哪里发生了数据倾斜
    去找找,代码那个地方,是哪个shuffle操作。

    数据倾斜解决方案之聚合源数据以及过滤导致倾斜的key

    第一个方法:聚合源数据

    第一个方案:聚合源数据
    咱们现在,做一些聚合的操作,groupByKey、reduceByKey;groupByKey,说白了,就是拿到每个key对应的values;reduceByKey,说白了,就是对每个key对应的values执行一定的计算。
    现在这些操作,比如groupByKey和reduceByKey,包括之前说的join。都是在spark作业中执行的。
    spark作业的数据来源,通常是哪里呢?90%的情况下,数据来源都是hive表(hdfs,大数据分布式存储系统)。hdfs上存储的大数据。hive表,hive表中的数据,通常是怎么出来的呢?有了spark以后,hive比较适合做什么事情?hive就是适合做离线的,晚上凌晨跑的,ETL(extract transform load,数据的采集、清洗、导入),hive sql,去做这些事情,从而去形成一个完整的hive中的数据仓库;说白了,数据仓库,就是一堆表。
    spark作业的源表,hive表,其实通常情况下来说,也是通过某些hive etl生成的。hive etl可能是晚上凌晨在那儿跑。今天跑昨天的数九。
    数据倾斜,某个key对应的80万数据,某些key对应几百条,某些key对应几十条;现在,咱们直接在生成hive表的hive etl中,对数据进行聚合。比如按key来分组,将key对应的所有的values,全部用一种特殊的格式,拼接到一个字符串里面去,比如“key=sessionid, value: action_seq=1|user_id=1|search_keyword=火锅|category_id=001;action_seq=2|user_id=1|search_keyword=涮肉|category_id=001”。
    对key进行group,在spark中,拿到key=sessionid,values;hive etl中,直接对key进行了聚合。那么也就意味着,每个key就只对应一条数据。在spark中,就不需要再去执行groupByKey+map这种操作了。直接对每个key对应的values字符串,map操作,进行你需要的操作即可。key,values串。
    spark中,可能对这个操作,就不需要执行shffule操作了,也就根本不可能导致数据倾斜。
    或者是,对每个key在hive etl中进行聚合,对所有values聚合一下,不一定是拼接起来,可能是直接进行计算。reduceByKey,计算函数,应用在hive etl中,每个key的values。
    聚合源数据方案,第二种做法
    你可能没有办法对每个key,就聚合出来一条数据;
    那么也可以做一个妥协;对每个key对应的数据,10万条;有好几个粒度,比如10万条里面包含了几个城市、几天、几个地区的数据,现在放粗粒度;直接就按照城市粒度,做一下聚合,几个城市,几天、几个地区粒度的数据,都给聚合起来。比如说
    city_id date area_id
    select ... from ... group by city_id
    尽量去聚合,减少每个key对应的数量,也许聚合到比较粗的粒度之后,原先有10万数据量的key,现在只有1万数据量。减轻数据倾斜的现象和问题。

    第二个方法:过滤导致倾斜的key

    第二个方案:过滤导致倾斜的key
    如果你能够接受某些数据,在spark作业中直接就摒弃掉,不使用。比如说,总共有100万个key。只有2个key,是数据量达到10万的。其他所有的key,对应的数量都是几十。
    这个时候,你自己可以去取舍,如果业务和需求可以理解和接受的话,在你从hive表查询源数据的时候,直接在sql中用where条件,过滤掉某几个key。
    那么这几个原先有大量数据,会导致数据倾斜的key,被过滤掉之后,那么在你的spark作业中,自然就不会发生数据倾斜了。

    数据倾斜解决方案之提高shuffle操作reduce并行度

    提升shuffle reduce并行度的缺陷

    很简单,主要给我们所有的shuffle算子,比如groupByKey、countByKey、reduceByKey。在调用的时候,传入进去一个参数。一个数字。那个数字,就代表了那个shuffle操作的reduce端的并行度。那么在进行shuffle操作的时候,就会对应着创建指定数量的reduce task。
    这样的话,就可以让每个reduce task分配到更少的数据。基本可以缓解数据倾斜的问题。
    比如说,原本某个task分配数据特别多,直接OOM,内存溢出了,程序没法运行,直接挂掉。按照log,找到发生数据倾斜的shuffle操作,给它传入一个并行度数字,这样的话,原先那个task分配到的数据,肯定会变少。就至少可以避免OOM的情况,程序至少是可以跑的。

    提升shuffle reduce并行度的缺陷

    治标不治本的意思,因为,它没有从根本上改变数据倾斜的本质和问题。不像第一个和第二个方案(直接避免了数据倾斜的发生)。原理没有改变,只是说,尽可能地去缓解和减轻shuffle reduce task的数据压力,以及数据倾斜的问题。
    实际生产环境中的经验。
    1、如果最理想的情况下,提升并行度以后,减轻了数据倾斜的问题,或者甚至可以让数据倾斜的现象忽略不计,那么就最好。就不用做其他的数据倾斜解决方案了。
    2、不太理想的情况下,就是比如之前某个task运行特别慢,要5个小时,现在稍微快了一点,变成了4个小时;或者是原先运行到某个task,直接OOM,现在至少不会OOM了,但是那个task运行特别慢,要5个小时才能跑完。
    那么,如果出现第二种情况的话,各位,就立即放弃第三种方案,开始去尝试和选择后面的四种方案。

    数据倾斜解决方案之使用随机key实现双重聚合

    数据倾斜解决方案之将reduce join转换为map join

    reduce join转换为map join,适合在什么样的情况下,可以来使用?
    如果两个RDD要进行join,其中一个RDD是比较小的。一个RDD是100万数据,一个RDD是1万数据。(一个RDD是1亿数据,一个RDD是100万数据)
    其中一个RDD必须是比较小的,broadcast出去那个小RDD的数据以后,就会在每个executor的block manager中都驻留一份。要确保你的内存足够存放那个小RDD中的数据
    这种方式下,根本不会发生shuffle操作,肯定也不会发生数据倾斜;从根本上杜绝了join操作可能导致的数据倾斜的问题;
    对于join中有数据倾斜的情况,大家尽量第一时间先考虑这种方式,效果非常好;如果某个RDD比较小的情况下。

    不适合的情况:
    两个RDD都比较大,那么这个时候,你去将其中一个RDD做成broadcast,就很笨拙了。很可能导致内存不足。最终导致内存溢出,程序挂掉。
    而且其中某些key(或者是某个key),还发生了数据倾斜;此时可以采用最后两种方式。
    对于join这种操作,不光是考虑数据倾斜的问题;即使是没有数据倾斜问题,也完全可以优先考虑,用我们讲的这种高级的reduce join转map join的技术,不要用普通的join,去通过shuffle,进行数据的join;完全可以通过简单的map,使用map join的方式,牺牲一点内存资源;在可行的情况下,优先这么使用。
    不走shuffle,直接走map,是不是性能也会高很多?这是肯定的。

    数据倾斜解决方案之sample采样倾斜key单独进行join

    这种方案什么时候适合使用?
    优先对于join,肯定是希望能够采用上一讲讲的,reduce join转换map join。两个RDD数据都比较大,那么就不要那么搞了。
    针对你的RDD的数据,你可以自己把它转换成一个中间表,或者是直接用countByKey()的方式,你可以看一下这个RDD各个key对应的数据量;此时如果你发现整个RDD就一个,或者少数几个key,是对应的数据量特别多;尽量建议,比如就是一个key对应的数据量特别多。
    此时可以采用咱们的这种方案,单拉出来那个最多的key;单独进行join,尽可能地将key分散到各个task上去进行join操作。

    什么时候不适用呢?
    如果一个RDD中,导致数据倾斜的key,特别多;那么此时,最好还是不要这样了;还是使用我们最后一个方案,终极的join数据倾斜的解决方案。

    就是说,咱们单拉出来了,一个或者少数几个可能会产生数据倾斜的key,然后还可以进行更加优化的一个操作;
    对于那个key,从另外一个要join的表中,也过滤出来一份数据,比如可能就只有一条数据。userid2infoRDD,一个userid key,就对应一条数据。
    然后呢,采取对那个只有一条数据的RDD,进行flatMap操作,打上100个随机数,作为前缀,返回100条数据。
    单独拉出来的可能产生数据倾斜的RDD,给每一条数据,都打上一个100以内的随机数,作为前缀。
    再去进行join,是不是性能就更好了。肯定可以将数据进行打散,去进行join。join完以后,可以执行map操作,去将之前打上的随机数,给去掉,然后再和另外一个普通RDD join以后的结果,进行union操作。

    数据倾斜解决方案之使用随机数以及扩容表进行join

    第一个模块的简单总结:
    1、完整的大数据项目开发流程:数据分析、需求分析、技术方案设计、数据表设计、代码编写、功能测试、性能调优、(上线)troubleshooting、(上线)解决数据倾斜问题。
    2、交互式大数据分析系统的架构:J2EE+Spark;
    3、基础组件:企业级大数据项目,spark工程,架构
    4、复杂的用户分析的业务:聚合统计、按时间比例随机抽取、复杂排序、取topn、用户行为分析
    5、spark的各种算子:map、reduce、join、group
    6、spark的高级技术点:自定义Accumulator、随机抽取算法、二次排序、分组取TopN
    7、性能调优:普通调优、jvm调优、shuffle调优、算子调优
    8、troubleshooting:多个实际生产环境中的,线上复杂报错问题的,剖析和解决方案
    9、(高端)全套的数据倾斜解决方案:原理+现象+定位、7种解决方案

  • 相关阅读:
    文件工具类之FileUtils
    JAVA8日期工具类
    mybatis模糊查询匹配汉字查询不出来数据,匹配字符和数字却可以的问题解决
    问到ConcurrentHashMap不要再提Segment了
    开发中常用工具
    Spring 如何解决循环依赖?
    JVM8基础概念总结
    String字符串相等判断
    面试再也不怕问到HashMap(二)
    面试再也不怕问到HashMap(一)
  • 原文地址:https://www.cnblogs.com/SteveDZC/p/13597022.html
Copyright © 2020-2023  润新知