• Spark——系统调优


    JVM层

    • 降低cache操作的内存占比

    Spark中,堆内存被划分成了两块:

    1. 专门用来给RDD的cache、persist操作进行RDD数据缓存用的;
    2. 用来给spark算子函数的运行使用的,存放函数中自己创建的对象。

    默认情况下,给RDD cache操作的内存占比是0.6,即60%的内存都给了cache操作了。但是问题是,如果某些情况下cache占用的内存并不需要占用那么大,

    问题在于task算子函数中创建的对象过多,然后内存又不太大,导致了频繁的minor gc,甚至频繁full gc,导致spark频繁的停止工作。性能影响会很大。

    针对上述这种情况,这个时候可以将其内存占比适当降低。怎么判断在什么时候调整RDD cache的内存占用比呢? 

    其实通过Spark监控平台就可以看到Spark作业的运行情况了,包括每个task的运行时间、gc时间等等。如果发现task频繁的gc,就可以去调整cache的内存占用比了。

    在代码中添加如下配置来设定:

    SparkConf.set("spark.storage.memoryFraction","0.6") 
    • 堆外内存的调整
    堆内存完全由 JVM 负责分配和释放,如果程序存在缺陷,有可能导致内存泄漏而溢出,抛出 OOM 异常: java.lang.OutOfMemoryError。
    除了堆内存,Java 还可以使用堆外内存,也称直接内存(Direct Memory)。顾名思义,堆外内存是在 JVM Heap 之外分配的内存块,并不是 JVM 规范中定义的内存区域。
    堆外内存可直接分配和释放,减少 GC 暂停时间,提高效率;可扩展,支持进程间共享,节省堆内存到堆外内存的拷贝等特点。如果程序存在缺陷,同样有可能导致堆外内存泄漏而溢出:OutOfDirectMemoryError
      • 问题提出

    有时候,如果你的spark作业处理的数据量特别特别大,几亿数据量;然后spark作业一运行就会出现类似shuffle file cannot find,executor、task lost,out of memory(内存溢出)等这样的错误。

    这是因为可能是说executor的堆外内存不太够用,导致executor在运行的过程中,可能会内存溢出;然后可能导致后续的stage的task在运行的时候,可能要从一些executor中去拉取shuffle map output文件,

    但是executor可能已经挂掉了,关联的blockmanager也没有了;所以可能会报shuffle  output file not found;resubmitting task;executor lost 这样的错误;最终导致spark作业彻底崩溃。

    上述情况下,就可以去考虑调节一下executor的堆外内存。也许就可以避免报错;此外,有时,堆外内存调节的比较大的时候,对于性能来说,也会带来一定的提升。

      • 解决方案

    在spark-submit脚本里面添加如下配置。默认情况下,这个堆外内存上限大概是300多M;我们通常项目中真正处理大数据的时候,这里都会出现问题导致spark作业反复崩溃无法运行;

    此时就会去调节这个参数,到至少1G或者更大的内存。通常这个参数调节上去以后,就会避免掉某些OOM的异常问题,同时呢,会让整体spark作业的性能,得到较大的提升。

    --conf spark.yarn.executor.memoryOverhead=2048

    注:看名字,顾名思义,以上设置针对的是基于yarn的提交模式

    • 连接等待时长的调整
      • 问题提出

    executor会优先从自己本地关联的BlockManager中获取某份数据。如果本地block manager没有的话,那么会通过TransferService,去远程连接其他节点上executor的block manager去获取。

    而此时上面executor去远程连接的那个executor,因为task创建的对象特别大,特别多, 频繁的让JVM堆内存满溢,正在进行垃圾回收。

    而处于垃圾回收过程中,所有的工作线程全部停止,相当于只要一旦进行垃圾回收,spark / executor停止工作,无法提供响应。 此时呢,就会没有响应,无法建立网络连接,会卡住。

    spark默认的网络连接的超时时长是60s;如果卡住60s都无法建立连接的话,那么就宣告失败了。碰到一种情况,有时候报错信息会出现一串类似file id not found,file lost的错误。

    这种情况下,很有可能是task需要处理的那份数据的executor在正在进行gc。所以拉取数据的时候,建立不了连接。然后超过默认60s以后,直接宣告失败。

    几次都拉取不到数据的话,可能会导致spark作业的崩溃。也可能会导致DAGScheduler,反复提交几次stage。TaskScheduler,反复提交几次task。大大延长我们的spark作业的运行时间。

      • 解决方案

    在spark-submit脚本中添加如上参数,调节这个值比较大以后,通常来说,可以避免部分的偶尔出现的某某文件拉取失败,某某文件lost掉的错误。

    --conf spark.core.connection.ack.wait.timeout=300
    • GC—G1参数
    spark.executor.extraJavaOptions -Dtag=mobius.optimize 
    -XX:+UseG1GC   #指定垃圾收集器
    -XX:G1HeapRegionSize=32m #设置的 G1 区域的大小
    -XX:MaxGCPauseMillis=200 #每次GC的目标停顿时间(默认值是 200 毫秒)。这是一个软目标,并且JVM将尽最大的努力来实现它,但不保证每次STW都严格小于该值
    -XX:G1NewSizePercent=5 #年轻代大小最小值的堆百分比(默认值是 Java 堆的 5%)。G1会根据MaxGCPauseMillis动态调整年轻代区的大小,但要保证占比肯定大于或等于该值
    -XX:G1MaxNewSizePercent=60 #轻代大小最大值的堆大小百分比(默认值是 Java 堆的 60%)
    -XX:MaxTenuringThreshold=1 #一个对象最多经历多少次young GC会被放入老年代(默认值是 15)
    -XX:ParallelGCThreads=10 #设置在垃圾收集器的并行阶段使用的线程数。缺省值随运行JVM的平台而异
    -XX:ConcGCThreads=8 #并发垃圾收集器将使用的线程数。缺省值随运行JVM的平台而异

    -XX:InitiatingHeapOccupancyPercent=45 #设置触发并发标记周期的 Java 堆占用率阈值(默认值占用率是整个 Java 堆的 45%)。G1开始进行并发标记的阈值,并发标记之后,就会进入Mixed GC周期
    -XX:G1MixedGCCountTarget=32 #一个Mixed GC 周期中最多执行多少次Mixed GC
    -XX:G1OldCSetRegionThresholdPercent=5 #一次Mixed GC 最多能回收多大的 OldRegion 空间
    -XX:G1ReservePercent=10 #设置作为空闲空间的预留内存百分比,以降低目标空间溢出的风险(默认值是 10%)

    -XX:-UseGCOverheadLimit #取消垃圾回收时的内存限制(减号)
    -XX:+UnlockDiagnosticVMOptions #解锁实验性虚拟机标志
    -XX:+G1SummarizeConcMark

    -verbose:gc  
    -XX:+PrintGC   #打印GC日志
    -XX:+PrintGCDetails #打印详细GC日志
    -XX:+PrintGCDateStamps #打印可读的日期时间戳 比如2018-11-12 17:22:15
    -XX:+PrintGCApplicationStoppedTime #打印应用停留时间
    -XX:+PrintHeapAtGC #在GC前后打印GC日志
    -XX:+PrintTenuringDistribution #打印各个年代对象分布
    -XX:+PrintAdaptiveSizePolicy #打印自适应大小策略
    -XX:+PrintFlagsFinal #打印java对象引用
    -XX:+PrintReferenceGC #打印垃圾对象的引用数量
    -Xloggc:/tmp/spark.gc.log #指定GC日志路径 (如果不指定,默认输出到各worker节点的$SPARK_HOME/work/$app_id/$executor_id/stdout中)
    -XX:+UseGCLogFileRotation #GC日志文件切割
    -XX:NumberOfGCLogFiles=10 #GC日志文件数量
    -XX:GCLogFileSize=128M #GC日志文件大小(单个)
    -XX:+PrintSafepointStatistics
    -XX:PrintSafepointStatistics=1
    -XX:PrintFLSStatistics=1

    引用:

  • 相关阅读:
    高斯消元(模板及bitset优化异或方程)
    dsu on tree
    拉格朗日插值
    [CF] CF900D Unusual Sequences
    【模板】Polya 定理
    Min-25筛学习笔记
    [CF] CF156C Cipher
    基于 Flink + Kafka 的广告实时数据分析建设与实践
    开源中国【面经】Java后台开发
    spring boot中连接数据库报错500(mybatis)
  • 原文地址:https://www.cnblogs.com/caoweixiong/p/13498278.html
Copyright © 2020-2023  润新知