spark OOM的解析和测试

前言

spark OOM的问题是在生产上经常发生的问题,今天来详细了解一下这块的情况,driver端的OOM没什么好说的,现在主要是讲一下executor端的内存的OOM情况
以上的结论都是通过看博客以及官网得出的结论

内存模型

在之前的文章我讲过内存模型,其实有一块还没讲就是这个参数,之前讲系统内存占到了0.4,spark.shuffle.memoryFraction 相关属于它的一部分,占到了它的一半 即0.2

spark.shuffle.memoryFraction

(deprecated) This is read only if spark.memory.useLegacyMode is enabled. Fraction of Java heap to use for aggregation and cogroups during shuffles. At any given time, the collective size of all in-memory maps used for shuffles is bounded by this limit, beyond which the contents will begin to spill to disk. If spills are often, consider increasing this value at the expense of spark.storage.memoryFraction.

大致含义为属于java heap的一部分,用于shuffle中的聚合和分组。在任何时候,用于shuffle的内存的总大小受此值限制。超过这个限制,那么就是spill到磁盘。如果经常溢写,那么应该增加这个值,牺牲spark.storage.memoryFraction值的大小。

个人理解:这个参数适用于当前stage向上一个stage拉取shuffle write的数据的操作。如果spark.shuffle.memoryFraction参数设置比shuffle write小的话,会造成溢写磁盘甚至OOM的操作

OOM具体分析

上面讲到了内存模型,然后看具体的示例。

/opt/beh/core/spark/bin/spark-submit --master yarn --class com.example.sparklearn.Test --num-executors 1 --executor-memory 2g --executor-cores 2 /home/hadoop/zgh/sparklearn-0.0.1-SNAPSHOT.jar

    val session = SparkSession
      .builder().enableHiveSupport().getOrCreate()

    val frame = session.read.csv("/user/zgh/ceshi/data.csv")

    val value = frame.rdd.map(x=>(x,1)).groupByKey().map(w => (w._1, w._2.sum))

    value.saveAsHadoopFile("/user/zgh/result",classOf[Text],classOf[IntWritable],classOf[TextOutputFormat[Text,IntWritable]])
    session.close()

我使用上面的示例代码以及提交命令,发生了OOM,如下图所示,


image.png

这块的原因就是因为 分配的spark.shuffle.memoryFraction 这块的内存小于溢写的内存。 但是我发现有时候他也会成功,原因在于因为有 Spill,理论上不会因为数据倾斜造成 OOM。 但是,由于对堆内对象的分配和释放是由 JVM 管理的,而 Spark 是通过采样获取已经使用的内存情况,有可能因为采样不准确而不能及时 Spill,导致OOM。

你可能感兴趣的:(spark OOM的解析和测试)