spark如何防止内存溢出

  1. MEMORY_AND_DISK
    使用rdd.persist(StorageLevel.MEMORY_AND_DISK)代替rdd.cache()
  2. 降低cache操作的内存占比
  3. 增加每个executor的内存量
  4. 使用kero序列化机制减少内存占用
  5. 避免使用partitions算子
  6. 数据倾斜,可能会导致每个task数据量太大,内存溢出
  7. 算子导致的内存溢出
    例如下列map算子,每条记录都产生了1000个对象,这肯定很容易产生内存溢出的问题
rdd.map(x=>for(i <- 1 to 10000) yield i.toString)

解决,分到更多的分区,减少每个task的压力

rdd.repartition(10000).map(x=>for(i <- 1 to 10000) yield i.toString)
  1. shuffle后内存溢出
    shuffle内存溢出的情况可以说都是shuffle后,单个文件过大导致的。在Spark中,join,reduceByKey这一类型的过程,都会有shuffle的过程,在shuffle的使用,需要传入一个partitioner,大部分Spark中的shuffle操作,默认的partitioner都是HashPatitioner,默认值是父RDD中最大的分区数,这个参数通过spark.default.parallelism控制(在spark-sql中用spark.sql.shuffle.partitions) , spark.default.parallelism参数只对HashPartitioner有效,所以如果是别的Partitioner或者自己实现的Partitioner就不能使用spark.default.parallelism这个参数来控制shuffle的并发量了。如果是别的partitioner导致的shuffle内存溢出,就需要从partitioner的代码增加partitions的数量。
  2. standalone模式下资源分配不均匀导致内存溢出
    在standalone的模式下如果配置了–total-executor-cores 和 --executor-memory 这两个参数,但是没有配置–executor-cores这个参数的话,就有可能导致,每个Executor的memory是一样的,但是cores的数量不同,那么在cores数量多的Executor中,就会执行多个Task,就容易导致内存溢出的情况。这种情况的解决方法就是同时配置–executor-cores或者spark.executor.cores参数,确保Executor资源分配均匀。

你可能感兴趣的:(#,spark内核,spark)