Doing More with Less: Orchestrating Serverless Applications without an Orchestrator

以库的形式,给每个function部署ingress和egress控制,实现分布式的串链调度。

Standalone orchestrator是一把双刃剑,一方面确实能够simplify development,但另一方面还会存在以下两个缺点: 一是灵活性不足、不能适用于所有应用;二是expensive to host and use。

为了实现application-level serverless orchestration,一个核心挑战是复杂有状态的orchestration pattern和强的执行保证。 这一点主要依托于scalable、strongly、consistent的数据存储解决。

Background

现有的两种解决办法

  1. trigger-based
  2. 不支持fan-n
  3. 每个function logic都要维护control-flow logic、笨重
  4. driver function
  5. 有运行时间限制
  6. double billing的问题

此外,以上两种orchestrator还需要开发者处理运维关系。

Standalone的问题

  1. hard
  2. yet another performance and scalability bottleneck
  3. expensive
  4. application-specific optimization

Design

主要是IR、一个ingress、一个egress。

IR支持三种调用

  • Invoke
  • Map
  • FanIN

基于此,还提供以下调用

  • Chain & Fan-out
  • Map
  • Branching
  • Aggregation和Fold(这两种在3.4节介绍)

Execution Guarantees Using Checkpoints

最重要的目标是实现exactly-once的执行。 为此,Unum提出了两个insight

  1. 即使同样的invocation会产生不同的结果,只要保证下游函数总被这些结果中的其中一个触发,这样的执行就是对的
  2. 即使一个函数被调用多次,只要调用使用的是相同的输入,工作流的输出就是正确的

基于此,Unum提出了checkpoint机制,实现create_if_not_exist函数。 一个函数执行完之后首先会尝试写入,如果已经存在了,该操作就会失败。 总之,后续函数的执行依赖于上游函数的第一个成功的调用。

Fault Tolerance

因为failed functions也会导致反复执行,因此这一个section主要讲了对failed functions的适配过程。 核心是保证a single value is always used to invoke downstream functions

Fan-in Patterns

Fan-in的挑战是所有branches结束后才能调用。 与其指定一个分支function作为coordinator,不如让所有分支都有权利在所有branch完成后调用函数。 具体操作就是每个branch完成后,都把自己写到一个set里面去,然后检查这个set的大小是否等于branch的个数。 如果等于就调用下游函数。

Garbage Collection

checkpoint和fan-in都维护了一些IR(checkpoints和coordination sets)。

对于checkpoint,垃圾回收机制由下游函数触发,因为它知道上游的checkpoint是不是还被需要。 在非fan-out情况下,一旦它自己生成了自己的checkpoint,就可以把上游的checkpoint删掉了。 在fan-out的情况下,维护一个类似于fan-in的set,每个branch生成了自己的checkpoint就把自己加入这个set里面,只要fan-out的branch个数等于set的大小,上游的checkpoint就可以删掉了。

fan-in类似。

Naming

需要一个确定的命名规则。

对于workflow invocation来说,在第一个函数入口处获取,要么自己生成、要么FaaS平台给。

对于function调用来说,由global function name、a vector of branch indexes和iteration numbers组成。