背景
这篇论文中采用容器化方案来实施ServerLess的落地过程,论文内部一方面基于大量的数据统计、一方面提出来FT树结构,用来优化容器冷启动。FAASNET是第一个为FaaS优化的容器运行时提供的端到端综合解决方案,FAASNET使用轻量级、分散和自适应的函数树来避免主要平台的瓶颈。
大会地址:https://www.usenix.org/conference/atc21/presentation/wang-ao
开源地址:https://github.com/mason-leap-lab/FaaSNet
一、网络流量的峰谷比
就如上图所示,不同的应用场景下,流量的高峰和低峰的请求比例是不一样的,比如游戏、IOT场景下流量的峰谷比高于22,这种峰谷比也表明了ServerLess场景的优势。
二、容器的冷启动情况
冷启动的延迟对于Faas提供商是致命的,阿里巴巴首先对于冷启动的分布情况作了调研:
- 对于北京地区,大约57%的镜像拉取时间超过45秒
- 对于上海地区,超过86%的镜像拉取时间至少需要80秒
- 显示超过50%和60%的函数调用请求花费至少80%和72%的整体函数启动时间来拉取容器镜像,这表明镜像拉取时间成为了大多数功能的冷启动成本。
冷启动的成本,还需要结合冷启动的间隔时间和功能持续时间来综合评价,在两个地区内部,大约49%的功能冷启动的到达时间小于1秒。
三、FAASNET技术内幕
在图3(d)中可以看出北京地区的80%函数执行时间超过1秒,上海地区80%的函数执行时间小于32.5秒,90th百分位数为36.6秒,99th百分位数为45.6秒。这种分布说明冷启动优化是必要的。
优化容器配置的性能将为降低基于容器的云功能的冷启动成本带来巨大的好处。
2.1 设计概述
FAASNET将跨虚拟机的容器配置分散化和并行化,引入了名为函数树(FT)的抽象,以实现高效的容器配置规模。FAASNET将FT管理器组件和一个工作者组件整合进入FAAS调度器和虚拟机代理中,以协调FT管理,阿里的Faas平台主要包含以下几个组成部分,工作的主体组成包括:
- 网关:租户身份管理认证,将函数请求转发给FAAS调度器,将常规的容器镜像转换为I/O高效数据结构,
- 一个调度器负责为函数调用请求提供服务,将FAASNET FT管理器集成到调度器来管理函数数、简称FT,通过FT的增删API进行管理。一个FT是一个二进制的树状覆盖,它连接多个虚拟机,形成一个快速和可扩展的容器供应网络。每个虚拟机运行一个FAAS代理,负责虚拟机本地的功能管理。将一个FAASNET工作者集成到VM代理中,用于容器的供应任务。
- 在函数调用的路径上,如果没有足够的虚拟机、或者所有的虚拟机都很忙的情况下,调度器首先与虚拟机管理器进行通信,从空闲的虚拟机池中扩展出活动的虚拟机池。然后调度器查询其本地的FT元数据,并向FT的FAASNET工作者发起RPC请求,从而启动容器供应流程。容器运行时供应过程实际上是分散的, 并在FT尚未有容器运行的本地供应的虚拟机进行准备工作。调度器在关键路径之外,而FAASNET工作层根据需求获取函数容器层,并从分配的对等虚拟机中并行地创建容器运行时。
- 在函数部署路径上,网关将函数的常规容器镜像转换为I/O的有效格式,从面向租户的容器注册表中提取常规镜像,逐块压缩镜像层,创建一个包含格式相关信息的元数据文件(镜像清单),并将转换后的层及其清单分别写入阿里云内部的容器注册表和元数据存储。
2.2 FT功能树
论文中针对重点强调在设计FT时做了以下选择:
- FT是和函数进行绑定的,FAASNET以函数为粒度来管理FT。
- FT具备解耦的数据面和控制面,FT的每个虚拟机工作者都具有等同的、简单的容器供应(数据平面)的角色,而全局树管理(控制平面)则交给调度器。
- FAASNET采用平衡的二叉树结构,可以动态的适应工作负载。
这些选择结合阿里云,可以达到以下目标:
- 最大限度的减少容器镜像和层数据下载的I/O负载。
- 消除中央根节点的树状管理瓶颈和数据播种瓶颈、这里阿里内部镜像采用P2P分发,播种友好。
- 适应虚拟机的动态加入和离开。
以函数的粒度管理树, FAASNET为每一个至少被调用过一次但未回收的函数管理一个单独、唯一的树。图5说明一个横跨5个虚拟机的三级FT拓扑结构。函数容器镜像从书的根部虚拟机往下流,直到达到叶子节点。
平衡的二叉树,FAASNET的核心是平衡的二进制树,在二进制树中,除了根节点和叶子节点,每个树节点(宿主虚拟机)有一条传入边和两条传出边。这种设计可以有效限制每个虚拟机的并发下载操作的数量,以避免网络争用。一个有N个节点的平衡二叉树的高度为log(N),这种关系也限制了函数镜像和层数据从顶部到底部的最多跳跃次数。树的高度会影响数据传播的效率,并且二叉树的结构可以动态变化,以适应工作负载的动态化。FAASNET把每个FT组织成一个平衡的二叉树,FT管理程序调用两个API:增加和删除,以动态地增加或缩小一个FT。
插入,FT的第一个节点会被当做根节点插入,FT管理器通过BFS(广度优先搜索)跟踪每个树节点的子节点数量,并将所有拥有0或1个子节点的节点存储在一个队列中。要插入一个新节点,FT管理器会从队列中挑选第一个节点作为新节点的父节点。
删除,调度器可能会回收闲置了一段时间的虚拟机(阿里云配置为15分钟),因此FAAS虚拟机的寿命是有限的。为了使用这种虚拟机的回收,FT管理器调用删除来回收虚拟机。删除操作也会在需要的时候重新平衡FT的结构。与二进制搜索树(如AVL、红黑树)不同,FT的节点没有可比较的键值(及其相关值)。因此,FT树的平衡算法只有当任何节点的左右子树的高度差大于1就会触发平衡操作。
2.3 FT与FAAS整合
论文中的FT整合是在阿里云的FAAS环境中,主要整合了FAAS平台的调度器和虚拟机代理。阿里把FAASNET的FT管理器集成到阿里云的FAAS调度器中,并将FAASNET的VM工作者集成到阿里云的FASS-VM代理中用于调度管理FT的虚拟机。
通过FT管理者,调度器在每个虚拟机代理上启动一个FAASNET工作者,工作者负责:
- 为调度员的命令提供服务,执行镜像下载和容器供应的任务
- 管理虚拟机上的函数容器。
FT元数据管理,调度器维护一个内存映射表,记录<functionID,FT>键值对,他将一个函数ID映射到其相关的FT数据结构。一个FT数据结构管理着一组代表函数和虚拟机的内存对象,以跟踪虚拟机的地址:端口信息。调度器是分片的,是高度可用的。每个调度器分片会定期将内存中的元数据状态与运行etcd的分布式元数据服务器同步。
函数在虚拟机上的放置,为了提高效率,FAASNET允许一个虚拟机容纳属于同一个用户的多个函数。只要虚拟机有足够的内存来承载函数,一个虚拟机可能参与到多个重叠的FT的拓扑结构中。
图8显示了一个可能的FT布局的例子,为了避免网络瓶颈,FAASNET限制了一台虚拟机可以放置的函数数量,目前设置是20个。
容器供应协议,FAASNET设计了一个协议来协调调度器和容器之间的RPC通信。
调度器和FAASNET的虚拟工人,并促进容器的供应。在一个调用请求中,如果调度器发现没有足够的活动虚拟机为请求提供服务,或者当前所有虚拟机都忙于为请求提供服务,调度员会从空闲的虚拟机池中保留一个或多个新的虚拟机,然后进入容器供应流程。
当调度器将函数元数据发送给VM,VM一旦收到信息会执行两个任务。从元数据存储库加载并检查清单,获取镜像层的URL,并把URL信息持久化到VM的本地存储中。VM回复调度器表明自己已经准备好开始为请求的函数创建容器运行时,调度器收到回复后向VM发送一个创建容器的RPC请求,VM处理清单配置,并向调度器发送一个RPC表明容器已经成功创建。
FT容错,调度器定期ping虚拟机,可以快速检测虚拟机故障。如果一个虚拟机发生故障,调度器会通知FT管理器执行树平衡操作以修复FT拓扑结构。
2.4 FT设计讨论
FAASNET将元数据繁重的管理任务卸载到现有的FAAS调度器上,因此每个单独节点都扮演着从其父级对等获取数据的相同角色。FT的根节点没有父级对等物,而是从注册表中获取数据。FAASNET的FT设计可以完全消除到注册中心的I/O流量,只要一个FT至少有一个活跃的虚拟机存储所请求的容器。早些时候,我们的工作负载分析显示,一个典型的FAAS应用的吞吐量将始终高于0RPS,在实践中请求突发更有可能讲一个FT规模从1到N,而不是从0到N。
另一种设计是更细粒度的层(blobs)来管理拓扑关系。在这种方法中,每个单独的层形成一个逻辑树层,属于一个函数的容器镜像的层最终可能驻留在不同的虚拟机上。注意FAASNET的FT是层树模型的一个特例。
图10中显示了一个例子,在这个例子中,一个虚拟机中存储着不同函数容器镜像的层文件,因此当许多下游的虚拟机同事从这个虚拟机获取层时,可能会出现网络瓶颈。这是因为许多重叠的层树形成了一个完全连接的、端对端的网络拓扑结构。如果虚拟机用高带宽的网络连接,全对全的拓扑结构可能会有很好的规模。然而如果每个虚拟机都收到了资源限制,全对全的拓扑结构很容易造成网络瓶颈,阿里云内部使用的是2核CPU、4G内存、1Gbps网络的小型VM。
现有的容器分配技术依靠强大的根节点来完成一系列任务,包括数据播种、元数据管理、P2P拓扑结构管理。将这些框架移植到FAAS平台上,需要额外的、专用的、分片的根节点,这将给运营商增加不必要的成本。另一方面,FAASNET的FT设计使每个虚拟机工作者的逻辑保持简单,同时所有的调度逻辑卸载到现有的调度器。这种设计自然消除了网络I/O瓶颈和根节点的瓶颈。Kraken采用了基于层的拓扑结构,具有强大根节点。
2.5 优化
I/O高效的数据格式,常规的docker pull 和 docker start是低效和耗时的,因为整个容器镜像和所有层的数据都必须从远程容器注册中心下载,然后才能启动容器。为了解决这个问题,阿里云内部设计了一个新的基于块的镜像获取机制,这种机制使用了一种I/O高效的压缩数据文件格式。原始数据被分割成固定大小的块,并分别进行压缩。一个偏离表被用来记录压缩文件中每个压缩块的偏移量。
FAASNET使用相同的数据格式来管理和配置代码包。一个代码包被压缩成一个二进制文件,它被虚拟机代码提取并最终安装在一个函数容器内。FAASNET分配代码包的方式与分配容器镜像的方式相同。
按需I/O,对于不需要在启动时一次性读取所有镜像层的应用程序,基于镜像块的获取方式提供了一个懒惰的按需方式从远程存储获取细粒度的镜像层数据。一个FAASNET的VM工作者从元数据存储中下载镜像的清单文件,并在本地进行镜像加载以加载.tar镜像清单,然后它计算第一个和最后一个压缩块的索引,然后查询偏移表以找到偏移信息。最后,它读取压缩块并解压,知道读取的数据量与要求的长度一致。由于底层(远程)块存储设备的读取必须是块边界对齐,应用程序可能会读取和解压比要求的更多的数据,造成读取放大。然而,在实践中,解压算法实现的数据吞吐量比块存储或网络的数据吞吐量高的多。在我们的使用场景中,用额外的CPU开销换取降低I/O成本是有益的。
RPC和数据流,FAASNET内部建立了一个用户态、零拷贝的RPC库。这种方法利用非阻塞的TCP sendmsg和recvmsg来传输一个 struct iovec 不连续的缓冲区。RPC库把RPC头直接添加到缓冲区,以便在用户空间实现高效、零拷贝的序列化。RPC库对请求进行标记、以实现请求流水线和失序接收,类似HTTP2的多路复用。当FAASNET工作者受到一个完整的数据块时,工作者会立即将该数据块传输给下游的节点。
三、FAASNET评测
3.1 实验方法
使用中等规模500个虚拟机池和一个大规模的1000个虚拟机池,所有的虚拟机均使用2核CPU、4GB内存、1Gbps网络的实例类型,维护一个免费的虚拟机池,FAASNET可以保留虚拟机实例来启动云函数。这样容器配置的延迟就不包括冷启动虚拟机实例的时间,FAASNET使用512KB的块大小,用于按需取用。
系统比较,FAASNET和一下三种配置进行比较。
- Kraken,Uber的基于P2P的注册系统。
- baseline,阿里巴巴云函数计算目前的生产设置,使用docker pull 从集中的容器中心下载镜像。
- on-demand,一个基于baseline的优化系统,但按需获取容器层数据。
- DADI+P2P,阿里巴巴的DADI启动了P2P,这种方法使用一个资源受限的虚拟机作为根节点来管理P2P拓扑结构。
目的,回答以下问题:
- FASSNET能否在突发的FaaS工作负载下迅速提供函数容器,并将工作负载性能的影响降至最低?
- FASSNET是否会随着调用量的增大而扩大规模?
- 函数放置策略如何影响FAASNET的效率?
- FAASNET的I/O高效数据格式的表现如何?
- FAASNET的按需获取数据的效果如何?
总结
FAASNET提供了一个具体的解决方案,通过实验评估表明,可以再几秒钟内启动成千上万的大型函数容器,具有很好的弹性。