Following the Data, Not the Function: Rethinking Function Orchestration in Serverless Computing 论文阅读

看得浑身难受,之后感觉悟了,但没有完全悟到。

之前 lxdg 说他们组想搞一个按数据自动编排任务流的东西,给用户有的数据和想要的数据,问怎么搞一个最小的编排,群友一通分析搞了个 BFS 感觉能行。

后来发现这 idea 挺好的,或许可以出题,然后就发现意思差不多的 idea 发 NSDI 了,哈哈。本身其实并没有撞 idea,只是理念是一样的。

论文在这里

Abstract

Serverless 程序通常由函数工作流组成,其中多个短生命周期的函数被触发,以响应事件或状态变化而交换数据。目前的 Serverless 平台通过遵循高层次的调用依赖关系来协调和触发函数,但对函数之间的底层数据交换却视而不见。这种设计在协调复杂的工作流时既不高效也不容易使用——开发人员往往不得不自己管理复杂的函数交互,并采用定制的实现方式,性能也不尽如人意。

在本文中,我们认为,函数协调应该遵循以数据为中心的方法。在我们的设计中,平台提供了一个 data bucket 的抽象,以保存函数产生的中间数据。开发者可以使用一套丰富的数据触发原语来控制每个函数的输出何时以及如何传递给工作流中的下一个函数。通过明确数据消费并允许其触发函数和驱动工作流,复杂的函数交互可以被轻松而有效地支持。我们提出了 Pheromone——一个遵循这种以数据为中心设计的可扩展、低延迟的 Serverless 平台。与成熟的商业和开源平台相比,Pheromone 将函数交互和数据交换的延迟减少了几个数量级,可扩展到大型工作流,并能轻松实现复杂的应用。

这篇文章面向的是 Serverless 中的数据管理,或者说数据编排,和 lxdg 的其实没啥关系,但是一说以数据为中心,那就一样了。这篇文章的贡献是造了一个 bucket,或者可以看成缓冲区,以整个 bucket 为触发器,而不是一条消息为触发器来触发函数运行,这个其实跟函数编排也就没啥关系了。

Introduction

Serverless 计算,也就是现在的 FaaS,广受开发者欢迎。FaaS 具有高扩展性,事件驱动性。开发者只需要把函数放在 Serverless 平台上,平台自己就可以进行资源准备,自动扩容,日志,容错等等。Serverless 是十分经济的,因为只有触发了函数才收费,平时没业务的时候不收费。

现在大伙都上云了,使用 Serverless 服务也有很多场景,比如不怎么常用的服务,监听服务等等就没必要起微服务一直占资源,写一个 FaaS 挂着,用的时候平台自己就会启动函数,十分方便,也更经济。文章中也列举了很多 Serverless 应用,这些应用通常由几个互相交互的函数组成,这些函数的交互形式和数据传输模式都有很大区别。比如,基于 Serverless 的批处理数分用 MapReduce 的 full-mesh 架构,流处理(比如 Apache Flink)可能在某些时间窗口反复触发某些函数来处理动态数据。

批处理和流处理是不一样的,批处理的特点是有界、持久、大量,非常适合需要访问全套记录才能完成的计算工作,一般用于离线统计。流处理的特点是无界、实时,无需针对整个数据集执行操作,而是对通过系统传输的每个数据项执行操作,一般用于实时统计。

Serverless 平台应该提供富有表达力的和易用的函数编排,来支持各异的函数交互和数据交换模式。这个编排还应该是高效的,使得函数交互是低延迟,并实现快速的数据交换。

然而目前的 Serverless 平台即不高效也不易用。Serverless 应用通常以工作流为模型,工作流按函数交互依赖来编排。它确定了函数交互的顺序,但忽视了函数之间何时以及如何交换数据。如果不知道函数之间如何交互,Serverless 平台就会假设一个函数的输出完全并立即被下一个或几个函数所消耗,而在许多应用中并非如此,例如上述批处理分析中的 shuffle 操作和流分析中动态积累数据的处理。这种情况下就需要比如消息代理,共享存储等来负责交换数据。但是这种方法逻辑复杂,延迟高,不能满足延迟敏感的应用需要。

这篇论文提供了一个 data bucket 的抽象,明确数据消费,然后让消费作为函数触发器。在设计中,Serverless 平台提供 data bucket 抽象来将中间输出装载进一个逻辑对象存储里。这个 bucket 提供一系列数据触发器原语,开发者可以指定什么时候和如何将中间数据传给目标函数并触发它们运行。使用这些原语,开发者可以通过统一接口配置数据触发器来表达复杂的函数交互和数据交换。知道了中间数据会被如何消费,就可以让 Serverless 平台靠近输入的下游目标函数,这样就可以实现快速的数据交换和低延迟函数交互了。

遵循以上设计方法,研究者开发了 Pheromone,一个可扩展的 Serverless 平台,支持以数据为中心的低延迟函数编排。它提出了三个关键设计来实现高性能:

  1. 使用两层分布式调度,尽可能在本地执行一个函数 workflow。每个工作节点都运行一个本地调度器,通过其 bucket 跟踪 workflow 的执行状态,并将 workflow 的下一个函数安排到本地。如果本地的所有 executor 都忙,调度器会将请求转发给全局协调器,然后将其转发给另一个有可用资源的工作节点。
  2. Pheromone 用中间数据的持久性(通常是短暂的、不可改变的)来换取快速的数据交换。函数通过零拷贝的共享内存对象存储来在节点内交换数据;它们也可以通过直接数据传输将数据传递给远程函数。
  3. Pheromone 使用分片的全局协调器,每个协调器处理一组不相干的工作流。有了这样一个无共享的设计,本地调度器只与相应的全局协调器同步工作流的执行状态,而全局协调器之间不需要同步,从而确保了分布式调度的高可扩展性。

实际上都是比较常见的高性能系统的设计模式。比如本地运行,本机共享内存,全局 coordinator 不同步啥的,感觉都比较一般。

研究者测试了开源的 Cloudburst,KNIX 和商业的 AWS,Azure 的 FaaS,结果是比开源最佳表现的 Cloudburst 快 10 倍,比商业最佳表现的 AWS Step Functions 快 450 倍。

这个结果感觉十分魔幻。

Pheromone 可以很好地扩展到大型工作流,在运行 1k 个链式函数和 4k 个并行函数时,只产生毫秒级的编排开销,而在其他平台上,开销至少要几秒钟。由于其零拷贝的数据交换,Pheromone 的数据交换开销可以忽略不计(例如,几十微秒)。它还可以通过有效的重新执行来处理运行失败的函数。两个 Serverless 应用的案例研究,即雅虎流处理和 MapReduce 排序,进一步证明了 Pheromone 可以轻松地表达复杂的函数交互模式(丰富的表达力),不需要具体的实现来处理函数之间的数据交换(高可用性),并有效地支持延迟敏感型和数据密集型应用(广泛的适用性)。

评价

这里之前的 Intro 看起来很好,但是实际上啥用没有。目标优化的场景类似于做 MapReduce,但是都做 MapReduce 了为什么要用 FaaS。用 FaaS 是为了省资源的,但是字节的 yarn 队列里每天都是满的,用 FaaS 能省出个啥出来。或者更 general 的,目标是优化数据迁移量大的 workflow,但是这种 workflow 举例举的全是数据分析,当然我能想到的也只有数分或者学习这样的场景涉及到大规模数据,一提到这种场景肯定上大规模集群来算,哪儿有 FaaS 的事。所以综合来看,FaaS 是好的,数据编排是好的,但是对 FaaS 做数据编排,哪儿有这种场景。相对于商业的提升 450 倍可能就来自于商业没需求,AWS 就没做,这个研究做了,那肯定提升的就多。

浑身难受就难受在这里了,尤其后面举例的用 FaaS 做数据分析的,我感觉在实用性上都得打个问号。但是也不好打问号,一半 SOSP 一半 NSDI,真不知道是谁有问题。

哦还举了 IPADS 的 WuKong,那我有问题,哈哈。

Principle 还是能看的,但是也就那样。

后面不想看了,摆了!