竞价实例跑 Serverless 工作流不怕被回收:FaaSpot 按 DAG 结构分级容错,成本降一半

举报
Eveline 发表于 2026/10/25 15:26:00 2026/10/25
【摘要】 竞价实例便宜,但长时 Serverless 工作流常因抢占级联失败。本文翻译 Middleware '26 论文 FaaSpot:提交时分析 DAG,只在扇出与汇合前写检查点,按存活概率提前扩容、从最近检查点重试,全程不回退按需实例,成功率 89%,单次成功成本不到最强基线一半。

原文信息:本文译自 arXiv 论文《FaaSpot: Fault-Tolerant Serverless Workflow Execution on Spot Instances》,作者 Bandhan Patel、Sushruth Harsha、In Kee Kim(美国佐治亚大学)与 Kwangsung Oh(内布拉斯加大学奥马哈分校),2026 年 10 月 19 日提交(arXiv:2610.26709),已被第 27 届 Middleware 国际会议(Middleware '26)录用。原文链接:https://arxiv.org/abs/2610.26709 。原文采用 CC BY 4.0 许可。本文为翻译(节译):摘要、引言、动机、设计与结论全文翻译,实现、实验与相关工作按原文要点节译;公式与伪代码改写为文字,图表与参考文献请见原文。文末附译者注。

译者导语:竞价实例(Spot Instance)便宜两到十倍,可一旦拿来跑几小时的 Serverless 工作流,中途被回收几乎是必然的。更糟的是,DAG 里一个扇出节点被抢占,所有并行分支都得陪着重来。这篇论文给出的办法很“工程”:提交时把 DAG 扫一遍,标出哪些位置一断就会连锁失败,然后只在这些位置做检查点、提前扩容、就近重试——全程不退回按需实例。对在云上跑批处理、数据流水线或科学计算工作流、又想压成本的工程师,很有参考价值。


摘要

Serverless 计算越来越多地用于运行复杂的 DAG 工作流,单个函数的执行时间也随之变长,工作流的总完成时间(makespan)被推到了小时级。部署在虚拟机池上的开源 Serverless 平台通常使用按需实例,成本随完成时间增长。竞价实例便宜得多,但工作流跑完之前很可能已经被抢占。扇出节点、或者给扇入节点供数的任务一旦被抢占,所有并行分支都会停住,一次抢占就会级联成整条工作流的失败。已有系统的做法是把高影响任务迁移到可靠的非竞价资源上,代价是放弃竞价实例的成本优势。

我们提出 FaaSpot:一个让工作流的每个任务都跑在竞价实例上、不回退到按需实例的 Serverless 工作流执行系统。我们的关键洞察是:容易引发级联失败的位置由 DAG 的拓扑结构决定,可以在执行前识别出来。因此,FaaSpot 在提交时对工作流 DAG 做一次分析,按“被抢占后的影响大小”给每个任务分级。选择性检查点、感知存活概率的扩容、基于血缘(lineage)的重试三种机制都以这份分级为依据,运行时无需互相协调。我们在一个基于真实轨迹的竞价实例仿真器上,用八个 DAG 工作流与四个业界先进基线做了对比。FaaSpot 的运行成功率达到 89.03%,每次成功运行的成本为 0.018 美元,成功率比基线平均高 21 个百分点,单次成功成本低于所有基线,平均延迟降低到原来的 1/2.3。

一、引言

Serverless 计算越来越多地用来执行复杂的有向无环图(DAG)工作流,覆盖数据分析、机器学习和科学计算等领域。这类工作流提交后运行到结束即终止,通常按计划或按实验反复运行。为支持这类应用,主流云厂商都推出了专门的编排服务,单个函数的执行时长上限也大幅放宽:Google Cloud 现在允许单个函数最长运行 60 分钟,Azure 当前的计划已取消执行时长限制,而早几代产品只有几分钟。于是,函数链更长、单函数运行更久,工作流的完成时间从几十分钟拉长到了几个小时。

除了托管服务,Fission、OpenWhisk 等自建的开源 Serverless 平台也越来越常见,运维方在自己的虚拟机池上运行 Serverless 基础设施。这些虚拟机通常是按需实例,基础设施成本随工作流时长增加。竞价实例便宜 2 到 10 倍,是显著降本的诱人选择。但对于要跑几十分钟到几个小时的工作流来说,竞价实例很可能在完成前就被回收。

我们测量了竞价抢占对工作流完成情况的影响:把一组 Serverless 工作流不加任何容错机制、直接(naive)部署到竞价虚拟机上。结果平均只有 39% 的运行能完成,而按需部署全部完成。抢占的影响很大程度上取决于它发生在工作流的哪个位置。顺序路径上的任务(本文中“任务”与“函数”同义,因为 Serverless 工作流里每个任务就是一个函数)被抢占,只影响它自己;而扇出节点、或给扇入节点供数的任务被抢占,会让共享它的所有并行分支停住,一次失败变成许多次。结果就是:少数几个结构上关键的位置,造成了大部分工作流失败。

竞价和临时资源上的容错,过去主要针对非 Serverless 负载。现有系统大多不考虑抢占发生在工作流的什么位置:要么对所有任务一视同仁地保护,要么在虚拟机层面被动应对,并不区分结构关键任务和普通任务(比如顺序路径上的任务)。少数系统(如 TR-Spark、Pado)会分析负载的 DAG,保护抢占代价最高的任务,但它们都依赖没有抢占风险的可靠资源,把这些可能引发级联的高影响任务迁到稳定存储或预留节点上。哪怕只是部分使用非竞价资源,也会削弱竞价实例的成本优势。要把优势吃满,就应该让尽可能多的负载(最好是全部)跑在竞价实例上,而这样一来,就没有可靠的地方来托管或迁移这些任务了。因此,上面这个关于结构的洞察,必须在没有可靠资源兜底的前提下,完整落实到竞价实例上的 Serverless 工作流中。

为此我们提出 FaaSpot。它让工作流的每个任务都跑在竞价实例上,不回退到按需实例。FaaSpot 的关键洞察是:那些一旦被抢占就会引发级联的位置,可以在执行开始前就识别出来,因为它们由 DAG 的拓扑决定,而不是由运行时状态决定。FaaSpot 在提交时分析一次 DAG,按抢占影响给每个任务分级。这一次离线分级驱动三个在线机制:

  1. 选择性检查点:只在高影响位置持久化状态;
  2. 感知存活概率的扩容:在抢占可能发生之前,把任务扩到更安全的实例上;
  3. 基于血缘的重试:失败的运行从最近的检查点恢复,而不是从头再来。

三种机制依据同一份分级,因此能一致地保护高影响任务,既不需要运行时协调,也不需要迁移到非竞价资源。最终效果是:竞价级别的成本,按需级别的可靠性。

我们实现了 FaaSpot 原型,并开发了一个基于真实轨迹的竞价实例仿真器来评估它。工作流集覆盖多个应用领域和多种结构,从简单的分叉-汇合(fork-join)图到复杂的真实流水线,包括 Epigenomics(表观基因组学)、LIGO(引力波探测)和 Montage(天文图像拼接)。在真实竞价实例上让 FaaSpot 和各基线遭遇完全相同的抢占事件极其困难,所以仿真器高保真地回放真实的竞价实例寿命和价格轨迹。仿真器与 FaaSpot 解耦,任何感知竞价的系统都能在相同抢占事件下接受评估。在八个工作流上,与四个先进的竞价容错系统相比,FaaSpot 平均完成 89.03% 的运行,每次成功运行 0.018 美元,成功率比基线平均高 21 个百分点,单次成功成本低于所有基线。即使对比最强的基线(成功率 81.78%,单次成功 0.040 美元),FaaSpot 也以不到一半的成本完成了更多运行,平均延迟降低到 1/2.3,在所有评估指标上全面领先。

本文的贡献:

  • FaaSpot:一个把 Serverless 工作流所有任务都放在竞价实例上执行、不回退按需实例的系统(第三节);
  • 一个统一的、感知失败的执行框架:用一次离线任务分级驱动选择性检查点、感知存活概率的扩容和基于血缘的重试,无需运行时协调即可一致地保护高影响任务(第四节);
  • 一个基于轨迹的评估框架:回放真实竞价寿命与价格轨迹,让多个感知竞价的工作流执行系统在相同抢占事件下进行公平、可复现的比较(第五、六节)。

二、动机

2.1 把 Serverless 工作流部署到竞价实例上

竞价实例比按需实例便宜得多,对 Serverless DAG 工作流很有吸引力。为了量化实际的成本收益和可靠性风险,我们用 Serverless 平台的默认配置把一组 DAG 工作流直接部署到竞价实例上:没有检查点,没有重试协调,也不迁移到按需实例。我们把这种配置称为“朴素部署”。在这种部署下,工作流中任何位置被抢占,整次运行都会失败。

测量使用基于轨迹的竞价仿真器(见 5.2 节),回放 SkyPilot 记录的 p3.2xlarge 竞价实例寿命轨迹,成本按 SpotLake 的实时竞价价格计算。每个工作流在相同轨迹条件下运行 500 次,便于与同一工作流的按需执行做配对比较。

对八个工作流的测量结果显示:

  • 成功率:在较复杂的工作流上,朴素部署的成功率远低于 50%,最低只有 13%,而按需部署每次都成功;
  • 单次成功成本:每个工作流上都低于按需实例,但优势不大;
  • 端到端延迟:比按需实例最多高 2.7 倍,因为每次失败都得从工作流起点(DAG 的第一个函数)重新开始。

这三项测量说明了竞价实例的长处和短处。成本优势还在,但很有限:每个工作流的单次成功成本都比按需便宜,但除最简单的那个工作流(便宜 43%)外,差距都在 30% 以下,最低只有 3%,远不及以往研究报告的 2 到 10 倍折扣。抢占导致的反复重跑吃掉了竞价的价格优势。延迟增加和高失败率则是直接而显著的代价。这个落差正是我们的机会:一套容错机制如果能把竞价的价格优势完整找回来,同时把延迟和失败率降到按需水平,价值会非常大。

2.2 为什么复杂工作流更容易失败?

复杂工作流的高失败率,不能只用任务数或执行时间来解释。主要原因是依赖结构,具体说是扇出节点和同步屏障。扇出节点被抢占,会阻塞它派生的所有并行分支。同步屏障是所有并行分支必须完成、在扇入节点汇合后才能继续往下执行的地方,因此任何一个给屏障供数的任务被抢占,都会让在屏障处等待的其他分支一起停住。wf-4(Epigenomics)、wf-5(LIGO)和 wf-8(Montage)三个工作流同时具有这两种模式。

把这三个工作流的成功率按阶段拆开(朴素部署,各 500 次):三者在第一阶段都接近 100%,之后单调下降,到最后一阶段只剩 13% 到 24% 的运行存活。降幅最大的是前几个阶段,因为这时全部运行都暴露在活跃并行分支的抢占风险之下。wf-5 在三个阶段内从 100% 跌到 37%,wf-8 在同样跨度内跌到 42%。每多一个阶段,就多一次在某处被抢占的机会,而任何一次抢占都可能让整次运行失败。

不同位置的代价并不相同。顺序路径上被抢占,只需重算这一个任务;扇出节点或同步屏障处被抢占,影响会传播到共享它的每个分支。

复杂工作流更容易失败,是因为高影响位置更多:扇出节点更多、并行更宽、同步屏障更深。同样的抢占频率,在复杂工作流上累积的失败代价更高。

这一规律并不局限于某个应用领域。wf-4、wf-5、wf-8 来自不同领域,DAG 拓扑各不相同,却都有相近的级联失败率。既然高影响的抢占位置可以在执行前从 DAG 静态推导出来,就可以有选择地保护它们,而不必一视同仁。

三、FaaSpot 系统概览

FaaSpot 通过容忍第二节描述的级联失败,让复杂的 Serverless 工作流能跑在竞价实例上,在不把任何任务迁出竞价实例的前提下,做到竞价级成本、按需级可靠性。下面介绍它的架构和背后的三条设计原则:用离线 DAG 分析识别并分级高影响抢占位置;用一份带关键度标注的 DAG 编码每个任务的结构风险,供所有容错决策共享;按任务的级联潜力分配不同强度的容错保护。

3.1 架构

FaaSpot 以 Serverless 工作流 DAG 为输入,分离线和在线两个协同阶段在竞价实例上执行它。

离线阶段有两个组件。任务排序器(task ranker)为每个任务计算一个关键度分数,量化它对下游的失败影响;检查点规划器(checkpoint planner)根据任务在 DAG 中的结构位置,把它分为 LOW、MEDIUM、CRITICAL 三级。关键度分数和分级在执行前计算一次,然后交给所有在线控制器。

在线阶段由三个控制器管理执行期的容错:检查点管理器、自适应扩缩器(adaptive scaler)和重试管理器。三者都基于离线阶段得到的同一份关键度分数和分级做决策。

FaaSpot 运行在一个 Serverless 执行平面和持久化存储之上。执行平面以开源 Serverless 平台 Fission 为控制面,把每个任务作为 Kubernetes Pod 运行在共享的竞价虚拟机池上。持久化存储保存检查点和血缘记录,供在线容错控制器恢复时使用。

范围与假设:FaaSpot 让工作流的每个任务都跑在竞价实例上,没有按需回退;但持久化存储和 Fission 控制面不在竞价实例上,它们也不会随工作流规模增长。设计假设 DAG 在提交时已经确定,并且能拿到每个任务的执行时间估计。

执行流程:执行平面派发任务时,检查点管理器查看每个任务的分级,高级别任务写检查点,最低级别跳过以减少开销。与此同时,自适应扩缩器根据每个竞价实例的已运行时长监测其存活概率;抢占风险上升时,就把工作流任务扩到更安全的实例上,安全实例池接近饱和时再申请新虚拟机。竞价实例一旦被抢占,重试管理器找出受影响的任务,让它们从最近的检查点恢复,而不是从工作流起点重来;自适应扩缩器也可能同时补充资源,保证执行持续推进。如此循环,直到所有任务完成。

3.2 三条设计原则

离线 DAG 分析。如果在运行时识别高影响抢占位置,往往需要边执行边分析 DAG,每次调度决策都会增加延迟。FaaSpot 依靠一个关键性质绕开了这笔开销:扇入、扇出节点是拓扑特征,与运行时状态无关,执行前识别一次,结果即可在所有容错决策中复用。

带关键度标注的 DAG。离线分析给每个任务标上关键度分数和分级,得到一份带关键度标注的 DAG。这是三个在线控制器之间唯一共享的状态。每个容错决策都基于同一份离线分级,而不是各自维护的运行时状态,所以无需运行时协调,决策天然一致。

分级容错。统一的检查点策略对所有任务一视同仁,会在顺序任务上产生不必要的 I/O 开销,而顺序任务重跑的代价本来就只限于它自己。FaaSpot 按任务被抢占后可能引发的级联范围把任务分为三级:

级别 结构位置 写检查点 能否作为恢复点
CRITICAL 扇出节点,或给扇入节点供数的任务 是 能,保住屏障之前的所有分支
MEDIUM 既非扇出节点、也不给扇入节点供数的并行任务 是 能,保住自己所在的分支
LOW 顺序路径上的任务,或扇入节点本身 否 不能,恢复时重放

这样,检查点管理器可以把检查点 I/O 集中在高影响位置,重试管理器也能优先恢复下游影响最大的任务。

四、感知失败的 Serverless 工作流执行

4.1 离线 DAG 分析

执行开始前,FaaSpot 用任务排序器和检查点规划器分析工作流 DAG,分别得到关键度分数和检查点分级,两者只算一次,然后交给在线控制器。

任务排序器。关键度分数同时反映从该任务出发的最长剩余路径和它的结构位置:分数高,说明这里被抢占会卡住大量后续任务;分数低,则只影响少数任务。FaaSpot 以 DAG 调度中常用的优先级指标 HEFT(Heterogeneous Earliest Finish Time,异构最早完成时间)为基础,HEFT 的基础排名等于任务自身执行时间加上其后继中最大的排名,也就是从该任务出发的最长剩余路径。任务排序器在此基础上再加两项结构计数——该任务派生的分支数、以及它所供数的屏障处会被卡住的分支数——然后在所有任务间做最小-最大归一化,得到关键度分数。扇出节点本来就因下游链路最长而有较高的 HEFT 排名,度数项则用来区分剩余路径相近的任务。自适应扩缩器只用这个分数的排序来决定扩容时谁先谁后。

检查点规划器。它根据任务的 minScale 给 DAG 中每个任务分级。minScale 指任务需要的并行函数数量:顺序任务为 1,以 k 个并行分支运行的任务为 k。分级规则如下:

  • CRITICAL:扇出节点,或给扇入节点供数的并行任务(其后继的 minScale 与自己不同);
  • MEDIUM:minScale 大于 1 且与后继相同的并行任务;
  • LOW:顺序路径上的任务或扇入节点本身(minScale 为 1 且与后继相同)。

minScale 发生变化的地方,恰好就是第二节指出的易级联位置。因此,分级反映的是“抢占会不会跨分支传播”,而不只是“重跑贵不贵”。举个例子:在 A → B →(C1→D1,C2→D2)→ E → F 这样的 DAG 中,扇出节点 B 和给扇入屏障供数的 D1、D2 为 CRITICAL,并行分支内部的 C1、C2 为 MEDIUM,顺序节点和扇入节点 A、E、F 为 LOW。检查点规划器与任务排序器并行,离线计算一次即可。

4.2 选择性检查点

运行时,工作流中的某个任务(DAG 中的一个节点,也就是一个函数)完成后,检查点管理器查看它的分级,决定是否把检查点写入持久化存储:CRITICAL 和 MEDIUM 任务完成时写检查点,LOW 任务跳过。这样,检查点 I/O 集中在 DAG 中易级联的位置——在这些地方留一份检查点能保住最多的下游工作;而顺序任务重跑代价只限于自身,就不必为它们付检查点的开销。

4.3 感知存活概率的扩容

这部分由自适应扩缩器负责:监测竞价实例的存活概率,在抢占风险上升时补充竞价虚拟机。它结合了三个机制:用 Kaplan-Meier 模型根据已运行时长估计每个实例的存活概率;用基于状态的策略决定扩容系数;用离线算好的 HEFT 排名决定扩容顺序,优先照顾高风险实例上的关键任务。

Kaplan-Meier 模型。以 AWS us-west-2a 区域 p3.2xlarge 竞价实例的条件存活曲线(来自 SkyPilot 轨迹)为例,存活概率在最初几小时内急剧下降,之后逐渐趋缓。这种随时间变化的规律,正是采用感知存活概率扩容策略的理由。FaaSpot 采用生存分析中标准的非参数方法 Kaplan-Meier 估计器,根据实例已运行时长估计其存活概率。不同实例类型、不同区域的抢占风险随运行时长的变化各不相同,没有哪一种分布能全部拟合;KM 模型直接从观测轨迹构建存活曲线,不预设任何分布。对一个已运行时间为 t 的竞价实例,KM 模型给出它在此基础上再存活一个时间窗口的条件概率,记作 S(t),从预先算好的曲线上直接查得。随后按 S(t) 把实例划入四个存活状态:

存活状态 存活概率 S(t) 扩容系数范围
0:安全 ≥ 0.55 1.0(不扩容)
1:主动 0.50 – 0.55 1.1 – 1.5
2:警告 0.40 – 0.50 1.3 – 1.8
3:危急 < 0.40 1.5 – 2.0

处于安全状态的实例无需干预,处于主动、警告、危急状态的实例是扩容候选。需要注意,在观测到足够多的抢占事件、能拟合出稳定曲线之前,KM 模型暂不启用。

基于状态的扩容。实例一旦落入非安全状态,跑在上面的工作流就有被抢占的风险,FaaSpot 会把工作流扩展到更安全的实例上来化解。剩下的问题是扩多少。扩容系数由存活状态决定:越接近抢占的状态,系数越大;每个状态对应一个区间,区间内的具体取值再按 KM 模型给出的 S(t) 浮动。每多一个副本就多一份成本,所以这是在抢占风险与额外开销之间做权衡。系数乘以当前每个运行中任务的并行度:minScale 为 m 的任务大约扩成“系数 × m”个副本,分布到更安全的虚拟机上。原文举的例子是:一台处于“警告”状态(系数在 1.3–1.8 区间内取值)的实例上的任务,据此扩出 6 个副本,部署到其他更安全的竞价虚拟机上。如果安全虚拟机池快满了,FaaSpot 会根据当前部署计划预判饱和,提前申请新虚拟机。

按 HEFT 排序扩容。扩容资源是有限的。为了在抢占下尽量多地完成工作流,FaaSpot 按 HEFT 排名给高风险实例上的任务排出扩容顺序。这样即使扩容因容量饱和而中断,CRITICAL 任务也更可能已经拿到了额外副本,从而降低级联失败的风险。

4.4 基于血缘的重试

重试管理器让被抢占的任务从最近的上游检查点恢复,而不是从工作流起点重来:只重放恢复点下游的子 DAG,并根据当前成功率与目标的差距来决定这一轮重试多少个。

基于检查点的恢复。任务被抢占时,重试管理器从失败任务沿 DAG 往回找恢复点。由于检查点在任务完成时写入,恢复点就是离它最近的、分级保证已写检查点的已完成前驱。执行从这里继续,只重放其下游的子 DAG。每次运行都有最大重试次数上限,按工作流规模设在 12 到 35 次之间;用完重试仍未完成的运行计为失败,这也是成功率达不到 100% 的原因。

重试批量大小。上面说的是单次失败运行如何恢复。实际中,共享竞价池里的抢占可能同时让多个工作流运行中断。如果把所有中断的运行立刻全部重试,它们会争抢同样有限的竞价容量。因此,重试管理器每轮只选一部分候选来重试:只有未达到重试上限的运行才有资格,每个候选按优先级打分——已完成的任务越多分数越高,已重试的次数越多分数越低,因此接近完成的运行优先重试。分级只间接影响这个顺序:从更高级别的检查点恢复能保住更多已完成任务。运维方为工作流指定一个目标成功率,重试管理器用目标与当前成功率之间的差距控制批量大小:差距大就激进恢复,差距小或为零就缩小批量、节省竞价容量。如果自适应扩缩器最近的扩容连续两轮以上都没能提升成功率,重试管理器会进一步放大批量,把恢复的重心从扩容转到重试上。

五、实现与仿真器(节译)

FaaSpot 用约 1.75 万行 Python 实现,运行在以 Fission 为 Serverless 执行平台的 Kubernetes 集群上;选 Fission 是因为它原生支持工作流、部署简单。所有运行时状态(检查点记录、重试历史、扩容决策)都持久化在 MySQL 中,检查点状态也写在这里,而这台 MySQL 跑在非竞价虚拟机上,抢占不会抹掉它。写入是事务性的,检查点写到一半失败时,上一个检查点保持完好,恢复会退回到它。离线分析的结果通过部署前生成的每任务 Kubernetes ConfigMap 分发给在线控制器。任务排序器在部署时作为独立进程运行,解析工作流定义(tasks.json)计算关键度;检查点规划器随后为每个任务分级并写入 ConfigMap;自适应扩缩器和重试管理器作为控制面上的独立子进程运行,按固定间隔轮询 Pod 运行时长或 MySQL 中的失败任务,并把决策记录回 MySQL。

在真实云竞价实例上评估不现实:一是竞价市场不断变化,前后运行的不同系统会遇到不同的中断序列,无法公平配对比较;二是在多个工作流、多种方法上大规模持续评估,既费钱又费时。为此作者开发了基于轨迹的竞价仿真器,目标有三:轨迹保真(用 SkyPilot 两周的多区域、多实例类型寿命轨迹和 SpotLake 历史价格)、公平评估(同一轮试验中所有方法遭遇完全相同的抢占事件)、与控制器无关(对外提供评估 API,任何感知竞价的系统都能接入)。仿真器以 60 倍加速时钟运行,在物理集群上用 Kubernetes Pod 代表竞价虚拟机,Pod 达到采样寿命即被“抢占”,其上所有容器一并终止,与真实云厂商行为一致;每轮试验用固定随机种子分配寿命,保证配对公平。

六、实验结果(节译)

实验设置:八个 DAG 工作流来自四个应用领域,除前面提到的 wf-4、wf-5、wf-8 外,还包括单对扇出/扇入的 fork-join(wf-2)、大规模扇出扇入的 1000Genome(wf-3)、双分支的 SRAsearch(wf-6)、多轮扇出扇入的 CyberShake(wf-7),以及只有一次扇出、没有同步屏障的紧凑 DAG(wf-1)。对比的四个基线是 Snape(用驱逐预测和约束强化学习动态调整竞价/按需比例)、Hourglass(把时间余量当风险预算,耗尽时回退按需)、MScheduler(借助应用原生重启和跨区域的成本选型恢复被抢占的 HPC 作业)和 Burst-HADS(在竞价与突发型实例上调度带截止时间的批量任务)。四者都不在检查点位置或重试顺序中考虑 DAG 结构。每个工作流每种方法每轮运行 500 次,重复 5 轮,使用 m3.2xlarge、p3.2xlarge、t3.2xlarge 三种实例和 AWS us-west-2a/2b 两个区域。成本只计算力;延迟包含排队、重试、检查点重放和函数启动开销,仅用于相对比较。

成功率与成本:

方法 平均成功率 单次成功成本
FaaSpot 89.03% ± 5.87 0.018 ± 0.007 美元
Snape 58.56% ± 6.17 0.050 ± 0.011 美元
Hourglass 76.22% ± 8.39 0.047 ± 0.011 美元
MScheduler 81.78% ± 7.95 0.040 ± 0.007 美元
Burst-HADS 53.43% ± 7.74 0.259 ± 0.071 美元

FaaSpot 在八个工作流中的七个上成功率最高、单次成功成本最低。差距最大的是 wf-5:FaaSpot 达到 86.2%,四个基线全都低于 41%。唯一的例外是 wf-4,MScheduler 成功率高出 2.5 个百分点(77.1% 对 74.6%),但单次成功成本是 0.067 美元,比 FaaSpot 的 0.055 美元高 22%。作者认为差距的根源在于基线做容错决策时不看 DAG 结构,把顺序路径上的抢占和易级联位置上的抢占同等对待。

端到端延迟:FaaSpot 平均 126 秒,比最接近的 Snape(297 秒)和 Burst-HADS(290 秒)低约 2.3 倍;p95 为 245 秒,而 Snape 为 704 秒、MScheduler 为 635 秒、Burst-HADS 为 1310 秒;p99 为 346 秒,Hourglass 和 Burst-HADS 分别为 2199 秒和 1897 秒。FaaSpot 在各分位上的跨工作流方差也最小(如 p50 为 ±42 秒,Snape 为 ±114 秒),延迟更可预测,因为它总是从最近的上游检查点恢复,而基线的恢复代价取决于抢占恰好落在 DAG 的哪里。

检查点效率:FaaSpot 平均每次成功运行写 10.6 个检查点,是所有方法中最少的;Snape 为 12.4 个(1.17 倍),MScheduler 为 19.6 个(1.8 倍),Hourglass 为 39.9 个(3.8 倍,它对每个任务都写检查点)。Snape 检查点较少,是因为它部分使用按需实例,暴露在抢占下的任务本来就少。

消融实验:

变体 平均成功率 单次成功成本
FaaSpot(完整) 89.03% 0.018 美元
A:去掉选择性检查点(改为每个任务都写) 86.44% 0.033 美元
B:去掉感知存活概率的扩容 86.74% 0.041 美元
C:去掉基于血缘的重试(检查点随之停用) 50.05% 0.082 美元

去掉选择性检查点或感知存活概率的扩容,成功率只小幅下降,但成本明显上升;去掉基于血缘的重试,成功率掉到一半左右。也就是说,基于血缘的重试是恢复能力的主要来源,另外两个机制提升的是恢复的效率。在三个高级联工作流上,变体 C 的成功率分别跌到 22.7%、25.9% 和 17.9%。在 wf-8 上,变体 A 的成功率略高于完整版(54.2% 对 51.7%),但单次成功成本更高(0.044 对 0.040 美元)——这正是选择性检查点有意做出的取舍。

参数敏感性:存活状态边界影响很大。把“安全”边界从 0.55 下调到 0.45(扩缩器更晚出手),wf-8 的成功率从 51.7% 跌到 27.0%,成本翻倍;上调边界能提高成功率,但会在不太可能被抢占的实例上浪费副本。重试批量大小的影响较小:批量调小在每个工作流上都更差;调大能提高 wf-5、wf-8 的成功率,但单次成功成本翻倍。默认设置在两者之间取得平衡。

七、局限性

  • 所有实验都在基于轨迹的仿真器上完成,而非真实云基础设施。仿真器保证了各方法面对相同抢占事件的公平性,但结果反映的是方法间的相对差异,而非生产环境的绝对数值。
  • 仿真器没有对检查点 I/O 延迟建模。由于 FaaSpot 写的检查点比所有基线都少,计入这部分开销只会让检查点更频繁的方法更吃亏,FaaSpot 的优势会进一步扩大。
  • 离线分级假设提交时 DAG 结构完全已知。有些科学工作流存在依赖数据的分支,每次运行的执行路径不同(如 DayDream),这类工作流不在当前范围内。用在线 DAG 细化扩展离线分析是自然的后续方向。
  • 任务排序器需要每个任务的执行时间估计,估计不准会改变关键度分数;不过扩缩器只用分数决定扩容顺序,只有顺序变了才有影响。分级则完全基于结构,所以顺序路径上一个运行很久的任务即使重跑代价很高也拿不到检查点,把执行时间纳入分级是后续工作。
  • 评估只用了三种实例类型和 AWS 两个区域。抢占率因区域和实例族而异,分布形状也取决于底层的可用性机制,因此部署到其他目标环境时,KM 存活模型和扩容阈值可能需要重新校准;这只影响自适应扩缩器,检查点和重试只依赖 DAG 结构。

八、相关工作(节译)

竞价与临时资源上的容错研究由来已久,涵盖最优检查点间隔、任务复制、竞价市场刻画和基于轨迹的可用性建模等。与 FaaSpot 最接近的是 TR-Spark 和 Pado,它们同样利用 DAG 结构保护损失代价最高的位置,但 TR-Spark 局限于 Spark 的同步阶段模型,Pado 依赖始终可用的预留节点。Serverless 工作流方面,Wukong、Speedo、Mashup、DayDream、ORION、WiseFuse、Jolteon、Dexter、MinFlow、Netherite 等工作分别优化了并行派发、混合部署、资源规格、函数合并、数据传递和状态持久化,但都没有把 Serverless DAG 执行与竞价实例池结合起来,竞价抢占给 Serverless 工作流带来的容错挑战此前尚未被系统研究。

九、结论

我们提出了 FaaSpot,一个应对复杂 DAG 工作流中竞价抢占所引发级联失败的 Serverless 工作流执行系统。已有系统靠把高影响任务迁到可靠的非竞价资源上来保护它们,牺牲了竞价的成本优势;FaaSpot 则在提交时对每个任务分级一次,并在三个在线机制之间共享这份分级,在竞价实例上保护同样的高影响位置,既不需要运行时协调,也不需要迁移。在自研的基于轨迹的竞价仿真器上、用八个 DAG 工作流做的评估表明,FaaSpot 的成功率达到 89.03%,单次成功成本 0.018 美元,在成功率、成本和延迟上同时优于四个业界先进基线。


译者注

  1. 核心思路可以直接借鉴:FaaSpot 最值得带走的不是某个参数,而是“按 DAG 结构分级保护”的工程判断——扇出点和屏障前的任务才值得写检查点,顺序任务失败了重跑就好。这条经验同样适用于 Airflow、Argo Workflows 等非 Serverless 编排:给扇出/汇合前的节点加结果持久化和“从断点续跑”,往往比给每个节点都加重试更划算。
  2. 落地时注意论文的边界:结果来自仿真器而非真实云,且只覆盖 AWS 两个区域、三种实例类型;检查点存储(MySQL)和控制面仍然放在按需实例上。在国内云上复现时,要先用自己区域、自己实例规格的回收记录重新拟合存活曲线并校准表中的阈值,否则扩容时机可能偏早或偏晚。另外,文中“函数最长 60 分钟/不限时”指的是 Google Cloud 和 Azure 的新规格,自建 Fission/OpenWhisk 才是本文的主要场景。
  3. 与华为云产品的关系:华为云弹性云服务器 ECS 提供竞价计费实例,云容器引擎 CCE 也支持竞价节点池;函数工作流 FunctionGraph 则提供函数流编排。若在 CCE 竞价节点上自建 Fission 一类的 Serverless 平台跑长时数据或科学计算流水线,可参考本文:把检查点写到不在竞价节点上的持久化存储(如云数据库或对象存储),按 DAG 结构挑选检查点位置,并结合节点运行时长提前做副本扩容。
【版权声明】本文为华为云社区用户翻译文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容, 举报邮箱:cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。