关于存储:MaxCompute执行引擎核心技术DAG揭秘

44次阅读

共计 12943 个字符,预计需要花费 33 分钟才能阅读完成。

简介:作为业界少有的 EB 级数据分布式平台,MaxCompute 每天撑持上千万个分布式作业的运行。这些作业特点各异,既有蕴含数十万计算节点的超大型作业,也有中小规模的分布式作业。不同用户对于不同规模 / 特点的作业,在运行工夫,资源应用效率,数据吞吐率等方面,也有着不同的期待。DAG 作为 MaxCompute 执行引擎的核心技术之一,在提供了底层对立的动静执行框架的同时,实现了一个在离线混合的执行模式(Bubble Execution),达到了均衡极致性能以及高效的资源利用率的目标。

作为业界少有的 EB 级别数据分布式平台,MaxCompute 零碎每天撑持上 千万 个分布式作业的运行。在这个量级的作业数目上,毫无疑问平台须要撑持的作业特点也多种多样:既有在 ” 阿里体量 ” 的大数据生态中独有的蕴含数十万计算节点的超大型作业,也有中小规模的分布式作业。同时不同用户对于不同规模 / 特点的作业,在运行工夫,资源应用效率,数据吞吐率等方面,也有着不同的期待。

Fig.1 MaxCompute 线上数据分析

基于作业的不同规模,以后 MaxCompute 平台提供了两种不同的运行模式,下表对于这两种模式做了总结比照:

Fig.2 离线 (batch) 模式 vs 一体化调度准实时 (smode) 模式

从上图能够看到,离线作业和一体化调度的准实时作业,在调度形式,数据传输,应用资源起源等多个方面,都有十分显著的区别。能够说,这两种运行形式别离代表了在海量数据场景上按需申请资源来 优化吞吐量和资源利用率 ,以及在解决中等(大量) 数据时通过计算节点的全量预拉起来 (以及数据直传等伎俩减速) 升高 执行时延 的两个极其。而这些区别,最终会通过执行工夫和作业资源利用率等方面体现进去。很显然,以 高 Throughput为次要优化指标的离线模式,和以谋求 低 Latency的准实时模式,在各方面的性能指标会有很大的区别。比方以 1TB-TPCH 规范 benchmark 为例,此报告执行工夫 (性能) 和资源耗费两个维度来做比拟。能够看到,准实时的 (SMODE) 在性能上有着非常明显的劣势 (2.3X),然而 这样的性能晋升也并不是没有代价的。在 TPCH 这个特定的场景上,一体化执行的 SMODE 模式,在获取了 2.3X 性能晋升的同时,也耗费了 3.2X 的系统资源(cpu * time)。

Fig.3 性能 / 资源耗费比拟:离线 (batch) 模式 vs 一体化调度准实时 (smode) 模式

这个察看论断其实并不意外,或者从某种程度上是 by design 的。拿下图一个典型 SQL 产生的 DAG 来看,所有计算节点都在作业提交伊始就被拉起,尽管这样的调度形式容许数据得以 (在须要的时候)pipeline 起来,从而可能减速数据的解决。但并不是所有的执行打算里的所有上下游计算节点都能够有理想化的 pipelined dataflow。事实上对于许多作业而言,除了 DAG 的根节点(下图中的 M 节点) 以外,上游的计算节点在某种程度上都存在着肯定水平的节约。

Fig.4 一体化调度准实时 (smode) 模式下,可能的资源应用低效

这种空转造成的资源应用的低效,在数据的解决流程上存在 barrier 算子而 无奈 pipeline,以及在 DAG 图比拟深 的状况下会尤为显著。当然对于心愿极致优化作业运行工夫的场景而言,通过更多的资源耗费,来获取极致的性能优化,在一些场景上是有其合理性的。 事实上,在一些 business-critical 的在线服务零碎中,为了保障服务总是能迅速响应并解决峰值数据,均匀个位数的 CPU 利用率也并非少见。然而对于计算平台这种量级的分布式系统,是否 在极致性能以及高效的资源利用率之间,获取一个更好的均衡呢

答案是必定的。这就是咱们在这里要介绍的混合计算模式:Bubble Execution

1. Bubble Execution 概述

DAG 框架的外围架构思维,在于对执行打算的逻辑层与物理层的清晰分层设计。物理执行图是通过对逻辑图中的节点、边等的物理个性 (如数据传输介质,调度机会,资源个性等) 的物化来实现的。比照在 Fig.2 中形容的 batch 模式和 smode 模式,DAG 提供了在一套灵便的调度执行框架之上,对立离线模式和准实时一体化执行模式的实现。如同下图所示,通过调整计算节点和数据连贯边的不同物理个性,不仅能对现有的两种计算模式做清晰的表述,在对其进行更通用化的扩大后,还能够摸索一种全新的混合运行模式,也就是 Bubble Execution。

Fig.5 DAG 框架上的多种计算模式

直观上来了解,如果咱们把一个 Bubble 当作一个大的调度单位,Bubble 外部的资源一起申请运行,并且外部上下游节点的数据均通过网络 / 内存直连传输。与之绝对的,Bubbles 之间连贯边上的数据传输,则通过落盘形式来传输。那么离线和准实时作业执行,其实 能够认为是 Bubble 执行的两个极其场景:离线模式能够认为是每个 stage 都独自作为 single-bubble 的特例,而准实时框架则是将作业所有计算节点都布局到一个大 Bubble 外部,来做一体化调度执行的另一个极其。DAG AM 曾经将两种计算模式对立到一套调度执行 infra 之上。使得在两种模式上进行长处互补成为可能,为引入 Bubble Execution 奠定了根底。

Bubble Execution 通过灵便自适应的子图 (Bubble) 切割,在现有的两个极其之间,提供了一种选取更细粒度,更通用的调度执行办法,达到作业性能和资源利用率之间获取优化的 tradeoff 的办法。在依据输出数据量、算子个性、作业规模等信息进行剖析后,DAG 的 Bubble 执行模式能够将一个离线作业切分出多个 Bubbles,在 Bubble 外部充分利用网络 / 内存直连和计算节点预热等形式晋升性能。这种切分形式下,一个 DAG 运行图中的计算节点,能够都被切入某个 Bubble,依据所在 DAG 中的地位被切入不同 Bubbles,还能够齐全不被切入任何 Bubble(仍然以传统离线作业模式运行)。这种高度灵便的混合运行模式,使整个作业的运行能更加灵便的自适应线上多种多样作业的特点,在理论生产中具备重要的意义:

  • Bubble 模式使更多作业的减速成为可能:一体化调度的准实时作业具备基于整体规模(线上默认 2000)的 ” 一刀切 ” 式的准入条件。这一方面是出于无限资源的偏心应用,另一方面也是为了管制节点 failure 带来的 cost。但对于中大型作业,尽管整体规模可能超过准入门限,然而其外部的不同子图,有可能是规模适合,且能够通过数据 pipeline 等办法来减速的。此外线上局部计算节点因为其自身的个性(比方蕴含 UDF 等用户逻辑须要平安沙箱),无奈应用预热的准实时资源池执行,而以后非黑即白的模式,会使得一个作业中,只有蕴含一个这种计算节点,整个作业都无奈应用减速模式执行。Bubble 模式能较好的解决这些问题。
  • Bubble 模式将 enable 线上两个资源池的买通:以后离线资源 (cold) 和准实时资源池 (warm) 作为两种个性不同的线上资源,齐全隔离,各自治理。这种拆散的现状,可能导致资源的节约。比方对于大规模作业,因为齐全无奈利用准实时资源池,排队期待离线资源,而同时准实时资源池可能正处于闲暇状态,反之亦然。Bubble 模式能通过在作业外部拉通不同资源的混合应用,使得两者各自补充,削峰填谷。
  • Bubble 模式能够整体上进步资源的利用率:从资源利用的角度来看,对于能够满足准实时模式准入的中型作业,因为准实时模式一体式调度拉起的运行模式,尽管运行速度能有所晋升,但主观上会造成肯定水平资源的空转与节约(尤其是 DAG 图较深以及计算逻辑有 barrier 时)。这种状况下,依照节点数目,计算 barrier 等条件,将一体化模式拆解成多个 Bubble。这可能无效的缩小节点大量的空转耗费,而且在拆分条件正当的状况下,性能方面的损失也能够做到较低。
  • Bubble 模式能无效升高单个计算节点 failure 带来的代价:一体化的准实时模式执行,因为其数据 pipeline 的个性,作业的容错粒度和其调度粒度是严密挂钩的:都是 all-in-one。也就是说,只有有一个节点运行失败,整个作业都要从新运行。因为作业规模越大,运行过程中可能有节点失败的概率也就越大,这样的 failover 粒度无疑也限度了其能反对的最大作业规模。而 Bubble 模式则提供了一个更好的平衡点:单个计算节点的失败,最多只影响同处于一个 Bubble 的节点。此外 Bubble 模式对于各种 failover 做了细粒度的各种解决,咱们将在下文形容。

咱们能够通过规范的 TPCH-1TB 测试 benchmark 来直观评测 Bubble 执行模式的成果。在下层计算引擎 (MaxCompute 优化器以及 runtime 等) 放弃不变,并且 Bubble 的大小维持在 500(具体 Bubble 切分规定下文介绍)时,做一下 Bubble 执行模式与规范离线模式,以及准实时模式,在性能 (Latency) 以及资源耗费(cpu * time) 两个方面的比拟:

Fig.6.a 性能 (Latency) 比拟:Bubble 模式 vs 离线 (batch) 模式 vs 一体化调度准实时 (smode) 模式

从运行工夫来看,Bubble 模式显然要远优于离线模式(整体 2X 的性能晋升),而较准实时的一体化调度模式而言,Bubble 的执行性能也并没有太显著的降落。当然在一些数据能够十分无效利用 pipeline 解决的 query(比方 Q5, Q8 等),准实时作业还是有肯定的劣势。但 SMODE 作业在执行工夫上的劣势并不是没有代价的,如果同时思考资源耗费,在下图中,咱们能够看到,准实时作业的性能晋升是建设在资源耗费远远大于 Bubble 模式的前提之上的。而 Bubble 在性能远优于离线模式的同时,其资源耗费,则整体上是相近的。

Fig.6.b 资源耗费 (cpu * time) 比拟:

Bubble 模式 vs 离线 (batch) 模式 vs 一体化调度准实时 (smode) 模式

综合起来看,Bubble Execution 能够很好的联合 batch 模式和准实时模式的长处:

  • 在执行工夫层面,对于 TPCH 测试集中的任意 query,bubble 模式的执行工夫都比 batch 模式要短,整体上 22 个 Queries 总耗时缩减将近 2X,靠近 service mode 模式的耗时;
  • 在资源耗费层面,bubble 模式基本上和 batch 模式相当,相比于 service mode 模式有大幅度的缩小,整体缩减 2.6X。

Fig.6.c Bubble 模式与离线 / 准实时模式的整体比拟

值得阐明的是,在下面的 TPCH Benchmark 比拟中,咱们把 Bubble 切分条件简单化了,也就是整体上之限度 bubble 的大小在 500,而没有充分考虑 barrier 等条件,如果在切分 bubble 的时候进一步调优,比方对于数据能够无效 pipeline 起来的节点,尽量保障切分在 bubble 外部,那作业的执行性能和资源利用率等方面都还能够进一步失去的晋升,这是咱们在理论生产零碎上线过程中会重视思考的。具体上线的成果见 Section 3。

在理解了 Bubble 执行模式的整体设计思维与架构后,接下来开展来讲一下具体 Bubble 模式的实现细节,以及将这种全新的混合执行模式推上线所须要的具体工作。

2. Bubble 的切分与执行

采纳 Bubble Execution 的作业(以下简称 Bubble 作业)和传统的离线作业一样,会通过一个 DAG master(aka. Application Master)来治理整个 DAG 的生命周期。AM 负责对 DAG 进行正当的 bubble 切分,以及对应的资源申请和调度运行。整体而言,Bubble 外部的计算节点,将依照计算加速度准则,包含同时应用预拉起的计算节点以及数据传输通过内存 / 网络直传进行 pipeline 减速。而不切在 bubble 外部的计算节点则通过经典离线模式执行,不在 bubble 外部的连贯边 (包含横跨 bubble boundary 的边) 上的数据,均通过落盘形式进行传输。

Fig.7 混合 Bubble 执行模式

Bubble 切分 办法,决定了作业的执行工夫和资源利用率。须要依据计算节点的并发规模,节点外部算子属性等信息综合思考。而在切分出 bubble 之后,Bubble 的执行 则波及到节点的执行,与数据 pipeline/barrier 的 shuffle 形式怎么做到有机的联合,这里离开做一下形容。

2.1 Bubble 切分原理

Bubble Execution 的核心思想在于将一个离线作业拆分成多个 Bubble 来执行。为了切分出有利于作业整体高效运行的 bubble,有几个因素须要综合思考:

  • 计算节点外部算子个性:对于同时拉起 bubble 所有计算节点的调度模式而言,数据在 bubble 外部的上下游节点之间是否无效的进行 pipeline 解决,很大水平上决定了在 bubble 外部,上游节点是否会因处于空转状态带来资源节约。所以在切分 bubble 的逻辑中,当节点蕴含 barrier 个性的算子而可能阻塞数据的 pipeline 时,将思考不将该节点与其上游切入同一个 bubble。
  • 单个 Bubble 外部计算节点数目的多少:如同之前探讨的,一体化的资源申请 / 运行,当蕴含的计算节点过多时,可能无奈申请到资源,或者即便能申请到其 failure 代价也可能无法控制。限定 Bubble 的大小,能够防止过大的一体化运行带来的负面作用。
  • 聚合计算节点,切割 Bubble 的迭代方向:思考到 bubble 大小的限度,从上而下切分 bubble 与从下而上切分 bubble 两种形式,可能导致切分的后果的不同。对于线上大部分作业而言,解决的数据往往呈倒三角型,对应的 DAG 也大多数是倒三角形态,所以默认采纳自底向上的算法来切割 bubble,也就是从间隔 root vertex 最远的节点开始迭代。

在上述的几个因素中,算子的 barrier 属性由下层计算引擎(e.g., MaxCompute 的 optimizer)给出。一般而言,依赖 global sort 操作的算子(比方 MergeJoin, SorteAggregate 等),会被认为会造成数据阻塞(barrier),而基于 hash 个性操作的算子则对于 pipeline 更加敌对。对于单个 Bubble 外部容许的计算节点数目,依据咱们对线上准实时作业特点的剖析和 Bubble 作业的理论灰度试验,选定的默认下限在 500。这是一个在大多数场景下比拟正当的值,既能保障比拟疾速的拿到全量资源,同时因为解决数据量和 DoP 根本成正相干关系,这个规模的 bubble 个别也不会呈现内存超限的问题。当然这些参数和配置,均容许作业级别通过配置进行微调,同时 Bubble 执行框架也会后继提供作业运行期间动静实时调整的能力。

在 DAG 的体系中,边连贯的物理属性之一,就是边连贯的上下游节点,是否有运行上的前后依赖关系。对于传统的离线模式,上下游先后运行,对应的是 sequential 的属性,咱们称之为 sequential edge。而对于 bubble 外部的上下游节点,是同时调度同时运行的,咱们称连贯这样的上下游节点的边,为 concurrent edge。能够留神到,这种 concurrent/sequential 的物理属性,在 bubble 利用场景上,理论与数据的传送形式 (网络 / 内存直传 vs 数据落盘) 的物理属性是重合的(Note: 但这两种仍然是离开的物理属性,比方在必要的时候 concurrent edge 上也能够通过数据落盘形式传送数据)。

基于这样的分层形象,Bubble 切分算法,实质上就是尝试聚合 DAG 图的节点,将不满足 bubble 准入条件的 concurrent edge 还原成 sequential edge 的过程。最终,由 concurrent edge 联通的子图即为 bubble。在这里咱们通过一个理论的例子来展现 Bubble 切分算法的工作原理。假如存在下图所示的 DAG 图,图中的圆圈示意计算顶点(vertex),每个圆圈中的数字示意该 vertex 对应的理论计算节点并发度。其中 V1 和 V3 因为在作业提交初始,就因为其外部蕴含 barrier 算子,而被标注成 barrier vertex。圆圈之间的连接线示意上下游的连贯边(edge)。橙色线代表(初始)concurrent edge,彩色线代表 sequential edge,初始状态图中的 sequential edge依据 barrier vertex 的输入边均为 sequential edge 的准则 确定,其余边默认均初始化为 concurrent edge。

Fig.8 示例 DAG 图(初始状态)

在这个初始 DAG 根底上,依照下面介绍过的整体准则,以及本章节最初形容的一些实现细节,上图形容的初始状态,能够通过多轮算法迭代,最终产生如下的 Bubble 切分后果。在这个后果中产生了两个 Bubbles: Bubble#0 [V2, V4, V7, V8],Bubble#1 [V6, V10],而其余的节点则被判断将应用离线模式运行。

Fig.9 示例 DAG 图 Bubble 切分后果

在上图的切分过程中,自底向上的遍历 vertex,并秉承如下准则:

若以后 vertex 不能退出 bubble,将其输出 edge 均还原为 sequential edge(比方 DAG 图中的 V9);

若以后 vertex 可能退出 bubble,执行广度优先遍历算法聚合生成 bubble,先检索输出 edge 连贯的 vertex,再检索输入 edge 连贯的,对于不能联通的 vertex,将 edge 还原为 sequential edge(比方 DAG 图中遍历 V2 的输入 vertex V5 时会因为 total task count 超过 500 触发 edge 还原)。

而对任意一个 vertex,只有当满足以下条件能力被增加到 bubble 中:

  • vertex 和以后 bubble 之间不存在 sequential edge 连贯;
  • vertex 和以后 bubble 不存在循环依赖,即:
    • Case#1:该 vertex 的所有 上游 vertex 中不存在某个 vertex 是以后 bubble 的 上游
    • Case#2:该 vertex 的所有 上游 vertex 中不存在某个 vertex 是以后 bubble 的 上游
    • Case#3:该 vertex 的所有 上游 bubble 中不存在某个 vertex 是以后 bubble 的 上游
    • Case#4:该 vertex 的所有 上游 bubble 中不存在某个 vertex 是以后 bubble 的 上游

注:这里的 上游 / 上游 不仅仅代表以后 vertex 的间接后继 / 前驱,也蕴含间接后继 / 前驱

Fig.10 切分 Bubble 过程可能存在循环依赖的几种场景

而理论线上 bubble 的切分还会思考到理论资源和预期运行工夫等信息,比方计算节点的 plan memory 是否超过肯定数值,计算节点中是否蕴含 UDF 算子,生产作业中计算节点基于历史信息(HBO)的预估执行工夫是否超长,等等,这里不再赘述。

2.2 Bubble 的调度与执行

2.2.1 Bubble 调度

为了实现计算的减速,Bubble 外部的计算节点的起源默认均来自常驻的预热资源池,这一点与准实时执行框架雷同。与此同时咱们提供了灵便的可插拔性,在必要的状况下,容许 Bubble 计算节点从 Resource Manager 当场申请(可通过配置切换)。

从调度机会上来看,一个 Bubble 外部的节点调度策略与其对应的输出边个性相干,能够分成上面几种状况:

  • 不存在任何 input edge 的 bubble root vertext(比方 Fig.9 中的 V2):作业一运行就被调度拉起。
  • 只有 sequential edge 输出 bubble root vertex(比方 Fig.9 中的 V6):期待上游节点完成度达到配置的 min fraction 比例(默认为 100%,即所有上游节点实现)才被调度。
  • Bubble 外部的 vertex(即所有输出边都是 concurrent edge,比方 Fig.9 中的 V4, V8, V10),因为其齐全是通过 concurrent edge 进行连贯的,会天然的被与上游同时触发调度。
  • Bubble 边界上存在 mixed-inputs 的 bubble root vertex(比方 Fig.9 中的 V7)。这种状况须要一些非凡解决,尽管 V7 与 V4 是通过 concurrent edge 链接,然而因为 V7 的调度同时被 V3 通过 sequential edge 管制,所以事实上须要期待 V3 实现 min-fraction 后能力调度 V7。对于这种场景,能够将 V3 的 min-fraction 配置为较小 (甚至 0) 来提前触发;此外 Bubble 外部咱们也提供了 progressive 调度的能力,对这种场景也会有帮忙。

比方图 7 中的 Bubble#1,只有一条 SequentialEdge 内部依赖边,当 V2 实现后,就会触发 V6 + V10(通过 concurrent edge)的整体调度,从而将整个 Bubble#1 运行起来。

在 Bubble 被触发调度后,会间接向 SMODE Admin 申请资源,默认应用的是一体化 Gang-Scheduling(GS)的资源申请模式,在这种模式下,整个 Bubble 会构建一个 request,发送给 Admin。当 Admin 有足够的资源来满足这个申请时,会将,再蕴含预拉起 worker 信息的调度后果发送给 bubble 作业的 AM。

Fig.11 Bubble 与 Admin 之间的资源交互

为了同时反对缓和资源上以及 Bubble 外部动静调整的场景,Bubble 同时还反对 Progressive 的资源申请模式。这种模式容许 Bubble 内的每个 Vertex 独立申请资源和调度。对于这种申请,Admin 只有有增量的资源调度即会将后果发送给 AM,直到对应 Vertex 的 request 齐全满足。对于这种场景上的独特利用这里临时不做开展。

在准实时执行框架降级后,SMODE 服务中的资源管理 (Admin) 和多 DAG 作业管理逻辑(MultiJobManager)曾经解耦,因而 bubble 模式中的资源申请逻辑,只须要和 Admin 进行交互,而不会对于失常准实时作业的 DAG 执行治理逻辑带来任何影响。另外,为了反对线上灰度热降级能力,Admin 治理的资源池中的每个常驻计算节点均通过 Agent+ 多 Labor 模式运行,在调度具体资源时,还会依据 AM 版本,进行 worker 版本的匹配,并调度满足条件的 labor 给 Bubble 作业。

2.2.2 Bubble 数据 Shuffle

对于穿梭 Bubble bourndary 上的 sequential edge,其上传输的数据和一般离线作业雷同,都是通过落盘的形式来进行数据传输。这里咱们次要探讨在 Bubble 外部的数据传输方式。依据之前形容的作业 bubble 切分准则,bubble 外部的通常具备充沛的数据 pipeline 个性,且数据量不大。因而对于 bubble 外部 concurrent edge 上的数据,均采纳执行速度最快的网络 / 内存直传形式来进行 shuffle。

这其中网络 shuffle 的形式和经典的准实时作业雷同,通过上游节点和上游节点之间建设 TCP 链接,进行网络直连发送数据。这种 push-based 的网络传送数据形式,要求上下游必须同时拉起,依据链式的依赖传递,这种网络 push 模式强依赖于 Gang-Scheduling,此外在容错,长尾躲避等问题上也限度了 bubble 的灵活性。

为了更好的解决以上问题,在 Bubble 模式上,摸索了内存 shuffle 模式。在这一模式下,上游节点将数据间接写到集群 ShuffleAgent(SA)的内存中,而上游节点则从 SA 中读取数据。内存 shuffle 模式的容错,扩大,包含在内存不够的时候将局部数据异步落盘保障更高的可用性等能力,由 ShuffleService 独立提供。这种模式能够同时反对 Gang-Scheduling/Progressive 两种调度模式,也使其具备了较强的可扩展性,比方能够通过 SA Locality 调度实现更多的 Local 数据读取,通过基于血统的 instance level retry 实现粒度更精密的容错机制等等。

Fig.12 Network Shuffle VS Memory Shuffle

鉴于内存 shuffle 提供的诸多可扩大劣势,这也是线上 Bubble 作业选用的默认 shuffle 形式,而网络直传则作为备选计划,容许在容错代价很小的超小规模作业上,通过配置应用。

2.3 Fault-Tolerance

作为一种全新的混合执行模式,Bubble 执行摸索了在离线作业和一体化调度的准实时作业间的各种细粒度均衡。在线上简单的集群中,运行过程中各种各样的失败在劫难逃。而 bubble 这种全新模式下,为了保障失败的影响最小,并在可靠性和作业性能之间获得最佳的均衡,其对于失败解决的策略也更加的多样化。

针对不同的异样问题,咱们设计了各种针对性容错策略,通过各种从细到粗的力度,解决执行过程中可能波及的各种异样场景解决,比方:向 admin 申请资源失败、bubble 中的 task 执行失败(bubble-rerun)、bubble 屡次执行失败的回退(bubble-renew),执行过程中 AM 产生 failover 等等。

2.3.1 Bubble Rerun

目前 Bubble 在外部计算节点失败时,默认采纳的 retry 策略是 rerun bubble。即当 bubble 内的某个节点的本次执行(attempt)失败,会立刻 rerun 整个 bubble,勾销正在执行的同一版本的 attempt。在偿还资源的同时,触发 bubble 从新执行。通过这种形式,保障 bubble 内所有计算节点对应的(retry) attempt 版本统一。

触发 bubble rerun 的场景有很多,比拟常见的有以下几种:

  • Instance Failed:计算节点执行失败,通常由下层引擎的 runtime 谬误触发(比方抛出 retryable-exception)。
  • Resource Revoked:在线上生产环境,有很多种场景会导致资源节点重启。比方所在的机器整机 oom、机器被加黑等。在 worker 被杀之后,重启之后的 worker 会按照最后的启动参数从新连回 admin。此时,admin 会将这个 worker 重启的音讯封装成 Resource Revoked 发送给对应的 AM,触发 bubble rerun。
  • Admin Failover: 因为 Bubble 作业所应用的计算资源来自于 SMODE 的 admin 资源池,当 admin 因为某些起因 Failover,或者 SMODE 整体服务被重启时,调配给 AM 的计算节点会被进行。Admin 在 Failover 之后不感知以后各个节点被调配的 AM 信息,无奈将这些重启的音讯发送给 AM。目前的解决办法是,每个 AM 订阅了 admin 对应的 nuwa,在 admin 重启之后会更新这个文件. AM 感知到信息更新后,会触发对应的 taskAttempt Failed,从而 rerun bubble。
  • Input Read Error:在计算节点执行时,读不到上游数据是一个很常见的谬误,对于 bubble 来说,这个谬误实际上有三种不同的类型:
    • Bubble 内的 InputReadError:因为 shuffle 数据源也在 bubble 内,在 rerun bubble 时,对应上游 task 也会重跑。不须要再做针对性的解决。
    • Bubble 边界处的 InputReadError: shuffle 数据源是上游离线 vertex(或也可能是另一个 bubble)中的 task 产生,InputReadError 会触发上游的 task 重跑,以后 bubble rerun 之后会被 delay 住,直到上游血统(lineage)的新版本数据全副 ready 之后再触发调度。
    • Bubble 上游的 InputReadError: 如果 bubble 上游的 task 呈现了 InputReadError,这个事件会触发 bubble 内的某个 task 重跑,此时因为该 task 依赖的内存 shuffle 数据曾经被开释,会触发整个 bubble rerun。

2.3.2 Bubble Renew

在 Admin 资源缓和时, Bubble 从 Admin 的资源申请可能等因为期待而超时。在一些异常情况下,比方 bubble 申请资源时刚好 onlinejob 服务处于重启的距离,也会呈现申请资源失败的状况。在这种状况下,bubble 内所有 vertex 都将回退成纯离线 vertex 状态执行。此外对于 rerun 次数超过下限的 bubble,也会触发 bubble renew。在 bubble renew 产生后,其外部所有边都还原成 sequential edge,并在所有 vertex 从新初始化之后,通过回放外部所有调度状态机触发事件,从新以纯离线的形式触发这些 vertex 的外部状态转换。确保以后 bubble 内的所有 vertex 在回退后,均会以经典离线的模式执行,从而无效的保障了作业可能失常 terminated。

Fig. 13 Bubble Renew

2.3.3 Bubble AM Failover

对于失常的离线作业,在 DAG 框架中,每个计算节点相干的外部调度事件都会被长久化存储,不便做计算节点级别的增量 failover。然而对于 bubble 作业来说,如果在 bubble 执行过程产生了 AM failover 重启,通过存储事件的 replay 来复原出的 bubble,有可能复原到 running 的中间状态。然而因为外部 shuffle 数据可能存储在内存而失落,复原成两头 running 状态的 bubble 内未实现的计算节点,会因读取不到上游 shuffle 数据而立即失败。

这实质上是因为在 Gang-Scheduled Bubble 的场景上,bubble 整体是作为 failover 的最小粒度存在的,所以一旦产生 AM 的 failover,复原粒度也应该在 bubble 这个层面上。所以对于 bubble 相干的所有调度事件,在运行中都会被当作一个整体,同时当 bubble 开始和完结的时候别离刷出 bubbleStartedEvent 和 bubbleFInishedEvent。一个 bubble 所有相干的 events 在 failover 后复原时会被作为一个整体,只有结尾的 bubbleFInishedEvent 才示意这个 bubble 能够被认为齐全完结,否则将重跑整个 bubble。

比方在下图这个例子中,DAG 中蕴含两个 Bubble(Bubble#0: {V1, V2}, Bubble#1: {V3, V4}),在产生 AM 重启时,Bubble#0 曾经 TERMINATED,并且写出 BubbleFinishedEvent。而 Bubble#1 中的 V3 也曾经 Terminated,然而 V4 处于 Running 状态,整个 Bubble #1 并没有达到终态。AM recover 之后,V1,V2 会复原为 Terminated 状态,而 Bubble#1 会重头开始执行。

Fig 14. AM Failover with Bubbles

3. 上线成果

以后 Bubble 模式曾经在公共云全量上线,SQL 作业中 34% 执行 Bubble,日均执行蕴含 176K 个 Bubble。

咱们针对 signature 雷同的 query 在 bubble execution 敞开和关上时进行比照,咱们发现在整体的资源耗费根本不变的根底上,作业的执行性能晋升了 34%,每秒解决的数据量晋升了 54%。

Fig 15. 执行性能 / 资源耗费比照

除了整体的比照之外,咱们针对 VIP 用户也进行了针对性的剖析,用户 Project 在关上了 Bubble 开关之后(下图中红色标记的点为关上 Bubble 的工夫点),作业的均匀执行性能有非常明显的晋升。

Fig 16. VIP 用户开启 Bubble 后均匀执行工夫比照

版权申明:本文内容由阿里云实名注册用户自发奉献,版权归原作者所有,阿里云开发者社区不领有其著作权,亦不承当相应法律责任。具体规定请查看《阿里云开发者社区用户服务协定》和《阿里云开发者社区知识产权爱护指引》。如果您发现本社区中有涉嫌剽窃的内容,填写侵权投诉表单进行举报,一经查实,本社区将立即删除涉嫌侵权内容。

正文完
 0