Spark 执行应用程序时,Spark 集群会启动 Driver 和 Executor 两种 JVM 进程,Driver 负责创建 SparkContext 上下文,提交任务,task 的分发等。 Executor 负责 task 的计算任务,并将结果返回给 Driver。同时需要为需 要持久化的 RDD 提供储存。Driver 端的内存管理比较简单,这里所说的 Spark 内存管理针对 Executor 端的内存管理。

Spark 内存管理分为静态内存管理和统一内存管理,Spark1.6 之前使用的 是静态内存管理,Spark1.6 之后引入了统一内存管理。

静态内存管理中存储内存、执行内存和其他内存的大小在 Spark 应用程序 运行期间均为固定的,但用户可以应用程序启动前进行配置。

统一内存管理与静态内存管理的区别在于储存内存和执行内存共享同一块空间,可以互相借用对方的空间。

Spark1.6 以上版本默认使用的是统一内存管理,可以通过参数 spark.memory.useLegacyMode 设置为 true(默认为 false)使用静态内存管理。

静态内存管理分布图
Spark 内存管理_内存管理
统一内存管理分布图
Spark 内存管理_scala_02
reduce 中 OOM 如何处理:

  • 减少每次拉取的数据量
  • 提高 shuffle 聚合的内存比例
  • 提高 Excutor 的总内存