深度 | EB级规模大数据平台核心技术揭秘(上)
凌云时刻
编者按:作为业界少有的EB级别数据分布式平台,MaxCompute系统每天支撑上千万个分布式作业的运行。DAG作为MaxCompute执行引擎的核心技术之一,在提供了底层统一的动态执行框架的同时,实现了一个在离线混合的执行模式(Bubble Execution),达到了平衡极致性能以及高效的资源利用率的目的。
作为业界少有的EB级别数据分布式平台,MaxCompute系统每天支撑上千万个分布式作业的运行。在这个量级的作业数目上,毫无疑问平台需要支撑的作业特点也多种多样:既有在"阿里体量"大数据生态中独有的、包含数十万计算节点的超大型作业,也有中小规模的分布式作业。同时,不同用户对于不同规模/特点的作业,在运行时间、资源使用效率、数据吞吐率等方面,也有着不同的期待。
Fig.1 MaxCompute线上数据分析
可以说,这两种运行方式分别代表了在海量数据场景上按需申请资源来优化吞吐量和资源利用率,以及在处理中等(少量)数据时通过计算节点的全量预拉起来(以及数据直传等手段加速)降低执行时延的两个极端。而这些区别,最终会通过执行时间和作业资源利用率等方面体现出来。
很显然,以高Throughput为主要优化目标的离线模式,和以追求低Latency的准实时模式,在各方面的性能指标会有很大的区别。
但并不是所有的执行计划里的所有上下游计算节点都可以有理想化的pipelined dataflow。事实上对于许多作业而言,除了DAG的根节点(下图中的M节点)以外,下游的计算节点在某种程度上都存在着一定程度的浪费。
事实上,在一些business-critical的在线服务系统中,为了保证服务总是能迅速响应并处理峰值数据,平均个位数的CPU利用率也并非少见。但是对于计算平台这种量级的分布式系统,能否在极致性能以及高效的资源利用率之间,获取一个更好的平衡呢?答案是肯定的。这就是我们在这里要介绍的混合计算模式:Bubble Execution。
Bubble Execution 概述
DAG框架的核心架构思想,在于对执行计划的逻辑层与物理层的清晰分层设计。物理执行图是通过对逻辑图中的节点、边等的物理特性(如数据传输介质,调度时机,资源特性等)的物化来实现的。对比在Fig.2中描述的batch模式和smode模式,DAG提供了在一套灵活的调度执行框架之上,统一离线模式和准实时一体化执行模式的实现。
那么离线和准实时作业执行,其实可以认为是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)模式
但SMODE作业在执行时间上的优势并不是没有代价的,如果同时考虑资源消耗,在下图中,我们可以看到,准实时作业的性能提升是建立在资源消耗远远大于Bubble模式的前提之上的。而Bubble在性能远优于离线模式的同时,其资源消耗,则整体上是相近的。
综合起来看,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内部,那作业的执行性能和资源利用率等方面都还可以进一步得到的提升,这是我们在实际生产系统上线过程中会注重考虑的。
「上篇」完。在了解了Bubble执行模式的整体设计思想与架构后,明天本公号将继续推送「下篇」,进一步展开来讲一下具体Bubble模式的实现细节,以及将这种全新的混合执行模式推上线所需要的具体工作。