Fireworks: A Fast, Efficient, and Safe Serverless Framework using VM-level post-JIT Snapshot

核心思想是协同利用VM级别的snapshot和runtime级别的JIT compilation。

Fireworks利用JIT的无服务器功能代码来减少函数的启动时间和执行时间,并通过共享JIT的代码来提高内存效率。此外,Fireworks还可以通过使用虚拟机作为沙盒来执行无服务器函数,从而提供高度的隔离性。

Background and Motivation

Characteristics of a Serverless Workload

  • Short function execution time
  • High consolidation in a server
  • Memory efficiency

Optimizing Serverless Platforms 对比的平台

  • Firecracker
  • OpenWhisk
  • gVisor
  • Cloudflare Workers
  • Catalyzer

Design

Design Overview

一共两个阶段

  • installation phase
    • 发信号给Firecracker,创建一个microVM
    • 将源代码添加注释
    • 调用函数,函数自己完成JIT。在entry point前创造一个snapshot
  • invocation phase
    • 当函数被调用后,setup a network for the microVM
    • restart VM snapshot
    • 读参数并正常执行

三个优点

高隔离度。Fireworks在一个单独的虚拟机(即Firecracker中的microVM)中运行每个虚拟服务器的功能,与使用容器或运行时作为沙盒的方法相比,提供了一个高隔离度。

高性能。Fireworks通过即时启动和JIT化的功能执行实现了高性能。 从本质上讲,Fireworks使用的是一个微虚拟机快照,它是在函数被加载和JIT化之后创建的。 由于JIT编译的代码比解释器更快,而且我们不需要在运行时支付JIT编译的成本,所以无服务器函数的执行时间大大减少。

内存效率。无服务器函数的多个实例可以以写时复制(CoW)的方式共享虚拟机级的内存快照。 Fireworks对快照使用私有映射(即MAP_PRIVATE),因此,如果没有变化,它就共享客体物理页;否则,它就依靠写时拷贝。 因此,快照共享microVM、操作系统、库、运行时,甚至JIT化代码的状态。只有在无服务器函数执行期间更新的特定参数执行状态不会被共享。

Automatic Source Code Annotation

Figure 3说的比较清楚了。

Python Numba对带有@jit(cache=True)的函数全部进行JIT编译。

Creating a post-JIT VM snapshot

Fireworks使用Firecracker API。然后Firecracker创建整个microVM的内存快照,并将快照存储在一个文件中。

Invoking a serverless function

当用户向无服务器函数发送请求时,Fireworks将请求的信息放入参数传递者队列,并向Firecracker管理程序请求恢复MicroVM。

一个microVM会以相应的快照图像重新启动。因此,调用无服务器函数只不过是把快照作为一个文件加载到内存中而已。

Fireworks在JIT化后的虚拟机快照镜像创建后立即恢复执行。

在恢复快照之前,Fireworks会配置网络并准备好参数传递,这样恢复后的微虚拟机就可以访问网络并获取所请求的函数的参数。

Enabling Network Connectivity

假设基于同一快照的多个microVM被启动。在这种情况下,microVM将有网络资源冲突--即每个从同一快照恢复的microVM将有相同的IP地址和MAC地址。

为了解决这个网络连接问题,Fireworks使用网络命名空间和网络地址转换(NAT)

Taking Serverless Function Arguments

Fireworks利用Kafka队列--一个软件消息总线--来向无服务器函数传递参数。