spark内存模型

Spark 1.6 开始使用了统一内存管理模块(UnifiedMemoryManager),并引入了堆外内存(Off-heap memory),1.6之前的内存管理就不进行介绍了。

spark堆内和堆外内存模型的示意图

(注意:堆外内存是依赖于worker的,而不是executor)

spark堆外(之所以叫spark堆外,是因为后续要和jvm堆外进行区别,也是大家容易弄混淆的地方),为了进一步优化内存的使用以及提高 Shuffle 时排序的效率,Spark 引入了堆外(Off-heap)内存,使之可以直接在工作节点的系统内存中开辟空间。Spark 可以直接操作堆外内存,减少了不必要的内存开销,以及频繁的 GC 扫描和回收,提升了处理性能。堆外内存可以被精确地申请和释放,而且序列化的数据占用的空间可以被精确计算,所以相比堆内内存来说降低了管理的难度,也降低了误差。

在默认情况下堆外内存并不启用,可通过配置 spark.memory.offHeap.enabled 参数启用,并由 spark.memory.offHeap.size 参数设定堆外空间的大小。除了没有 other 空间,堆外内存与堆内内存的划分方式相同,所有运行中的并发任务共享存储内存和执行内存。

堆外内存由于默认不开启堆外内存,以及笔者没有使用堆外内存的客观收益证明,这里不进行详细讨论

spark堆内spark 堆内内存就是spark提交给jvm管理的那部分内存(与直接操作系统内存对应),spark 对堆内内存的管理是一种逻辑上的"规划式"的管理,因为对象实例占用内存的申请和释放都由 JVM 完成,Spark 只能在申请后和释放前记录这些内存。这也是为什么堆内占用没法被精确计算(非序列化的对象),以及内存使用情况无法精确得知(无法清楚得知jvm的GC情况)的原因。

spark堆内内存模型示意图

如图所示,spark.{executor/driver}.memory参数来设置堆内存, spark.yarn.{executor/driver}.memoryOverhead 来设置堆外内存。

(注意:这里的memoryOverhead所指的堆外内存是jvm控制的堆外内存,与上面说的spark堆外内存不是一回事)

由于executor和driver的内存模型结构相同,这里以executor为例来进行说明

Execution 内存:主要用于存放 Shuffle、Join、Sort、Aggregation 等计算过程中的临时数据

Storage 内存:主要用于存储 spark 的 cache 数据,例如RDD的缓存、unroll数据;

用户内存(User Memory):主要用于存储 RDD 转换操作所需要的数据,例如 RDD 依赖等信息,对于sparkSQL而言还有UDF的内存占用。注意:这部分数据无法spill到磁盘,如果不够就会OOM

预留内存(Reserved Memory):系统预留内存,会用来存储Spark内部对象。

(注意:公司集群中,spark.memory.fraction的默认值是0.3)

jvm堆外内存的模型

其中堆外内存的Execution和Storage作用和堆内内存相同

参数调优指南(Spark内存模型以及调参建议

(注意:executor的内存溢出绝大多数情况是由于数据倾斜,所以优先要解决数据倾斜的问题,参数的调优只是在非数据倾斜下才有明显收益)

出错点

表现

建议

Executor 堆内存不足

在XT的测试日志或者Spark Driver日志中发现Executor的退出码为143:“Exit status: 143”,例如:

Diagnostics: Container killed on request. Exit code is 143

Container exited with a non-zero exit code 143

Killed by external signal

  1. 如果executor-cores 比较大(>2), 首先减小executor-cores

  2. 如果executor-cores 比较小,增大spark.executor.memory

在XT测试日志或者SparkUI中发现如下日志“Executor heartbeat timed out”,例如:

ExecutorLostFailure(executor 923 exited caused by one of the running tasks) Reason: Executor heartbeat timed out after 167123 ms

Executor 堆外内存不足

在XT测测试日志或者Spark UI中出现“Consider boosting spark.yarn.executor.memoryOverhead”,例如

ExecutorLostFailure (executor 29 exited caused by one of the running tasks)

Reason: Container killed by YARN for exceeding memory limits. 3.1 GB of 3 GB physical memory used.

Consider boosting spark.yarn.executor.memoryOverhead.

  1. 如果executor-cores 比较大(>2), 首先减小executor-cores

  2. 如果executor-cores 比较小,增大

    spark.yarn.executor.memoryOverhead

Driver内存不足

XT测试日志中频繁出现“WARN Client: Fail to get RpcResponse: Timeout”

  1. 怀疑大表被广播,检查一下是否有将spark.sql.autoBroadcastJoinThreshold设置比较大,或者对大表加了广播的hint(mapjoin、broadcast)

  2. 检查是否向Driver collect大量数据

  3. 增大spark.driver.memory

JobSearch 出现“Application application_1556014017728_7970183 failed 1 times due to ApplicationMaster for attempt appattempt_1556014017728_7970183_000001 timed out. Failing the application.”, 例如

Driver压力大,不能及时响应Executor的心跳信息

ExecutorLostFailure (executor 696 exited caused by one of the running tasks) Reason: Container marked as failed: container_e17_1560590242140_874934_01_000898 on host: zw02-data-hdp-dn6412.gh.sankuai.com. Exit status: 56.

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spark内存模型是指Spark内存中管理和处理数据的方式。Spark使用了一种称为弹性分布式数据集(Resilient Distributed Dataset,简称RDD)的数据结构来表示和操作数据。 RDD是一个可分区、可并行计算的数据集合,它可以在集群中的多个节点上进行并行处理。RDD的特点是不可变性和容错性,即RDD的数据是只读的,一旦创建就不能修改,同时RDD会自动记录数据的血统信息,以便在节点故障时进行恢复。 Spark内存模型主要包括以下几个部分: 1. Driver:驱动器是Spark应用程序的主要控制节点,负责整个应用程序的调度和协调工作。驱动器程序会将应用程序划分为一系列的任务,并将这些任务分发给集群中的工作节点进行执行。 2. Executor:执行器是运行在集群中的工作节点上的进程,负责执行驱动器分发的任务。每个执行器都有自己的JVM进程,并且可以同时运行多个任务。执行器通过与驱动器通信来接收任务,并将任务结果返回给驱动器。 3. RDD:RDD是Spark中的核心数据结构,它代表了一个可分区、可并行计算的数据集合。RDD可以从外部数据源创建,也可以通过对其他RDD进行转换操作得到。RDD的数据可以被分区存储在内存中,以便并行处理。 4. 分区:RDD的数据可以被划分为多个分区,每个分区都是一个独立的数据片段。分区是Spark并行计算的基本单位,每个分区可以在一个执行器上进行处理。分区的数量决定了并行计算的程度。 5. 内存管理:Spark使用内存来缓存RDD的数据,以便加速后续的计算操作。Spark提供了两种类型的内存管理方式:堆内存和堆外内存。堆内存用于存储RDD的元数据和执行过程中的临时数据,而堆外内存则用于缓存RDD的数据分区。 6. 数据共享:Spark通过共享RDD的方式来实现数据的复用和传递。当一个RDD被多个任务使用时,Spark会将该RDD的数据分区复制到各个任务所在的执行器上,以便并行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值