You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spark作业间共享存储级别为NONE的RDD为何仍有4倍性能提升?

问题:Spark作业间复用存储级别为NONE的RDD为何仍有性能提升?

我有多个Spark作业,它们共享包含昂贵shuffle操作的部分数据流图。若持久化该RDD,如预期般获得了22倍的性能提升。
但即便将这些RDD的存储级别设为NONE,仅在作业间共享RDD仍能获得最高4倍的性能提升。
这是为什么?我原本认为Spark总会重新计算存储级别为NONE的RDD,且这类RDD不会被逐出或溢写。

我的Spark版本为3.3.1,核心操作如下:

  1. 通过自定义的 lineage traces[1] 识别作业间重复且昂贵的Spark操作;
  2. 首次执行这些操作后,将RDD句柄缓存到本地哈希表<lineage-trace, RDD>中;
  3. 后续遇到相同操作时,直接复用缓存的RDD。

若在第二步调用rdd.persist(StorageLevel.MEMORY_AND_DISK)持久化RDD,性能提升显著,但仅复用存储级别为NONE的同一RDD时,仍能看到性能提升。

[1] LIMA:机器学习系统中的细粒度 lineage 追踪与复用。Arnab Phani, Benjamin Rath, Matthias Boehm. SIGMOD 2021


问题解答

即使将RDD的存储级别设为NONE,作业间复用同一RDD仍能获得性能提升,主要源于以下几个Spark底层机制的特性:

  • Shuffle输出的自动复用:Spark的shuffle阶段输出默认会在集群节点上保留一段时间(可通过spark.shuffle.service.enabled、spark.shuffle.service.cleanup.interval等参数配置),这个保留逻辑和RDD的存储级别无关。当后续作业复用包含shuffle的RDD时,Spark可以直接读取之前作业生成的shuffle输出文件,无需重新执行昂贵的shuffle操作——这是4倍性能提升的核心原因。

  • DAG计算路径的简化:复用RDD句柄后,后续作业的计算DAG会直接从该RDD开始,跳过了上游所有的计算步骤(比如数据源读取、前置的map/filter转换等)。虽然这些步骤的开销不如shuffle大,但累积起来也能减少大量重复计算。

  • 任务调度与执行的开销节省:重新构建完整DAG需要调度所有上游任务,包括任务的序列化、分发、启动等流程。复用RDD后,调度的任务数量大幅减少,节省了这部分额外的overhead。

需要注意的是,这种复用依赖于shuffle输出未被清理,一旦shuffle文件被后台清理进程删除,后续作业就会重新计算整个DAG,性能提升就会消失。而使用MEMORY_AND_DISK持久化时,RDD数据会主动存储并受Spark缓存管理,不会依赖shuffle文件的临时保留,因此性能提升更稳定且幅度更大(22倍)。


内容的提问来源于stack exchange,提问作者Phaniarnab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 01:31:02