论文阅读笔记(五):Cloud Programming Simplified: A Berkeley View on Serverless Computing
原文链接:Cloud Programming Simplified: A Berkeley View on Serverless Computing
不愧是世界一流学府,对实时技术的把握精准且及时。2009年,UCB发表了关于云计算的文章,并且预测了挑战与需要解决的问题,2019年,他们发表此篇文章,对无服务进行了一番探讨。文章总体分为了8个部分,我们看看核心的4个部分说了什么。
对无服务计算的介绍
在2009年,UCB的学者就曾经对云计算提出过一些观点,主要在以下六方面有很大的优势:
- 无限的计算资源可以按需分配
- 消除云用户的前期承诺(其实和第一点类似,都是根据需求提供计算服务,不用再提前算好可能需要的计算力)
- 根据实际需要支付短期使用计算资源的费用
- 规模经济显著降低了成本,因为数据中心非常大
- 通过资源虚拟化简化操作成本,提升使用率
- 通过多路复用技术,分担不同组织的负载,提升硬件利用率
过去十年间,上述优势基本都被实现了,但是最后两点实现的并不好。因此,云用户依然忍受着操作复杂的缺点,同时也没有从高效的多路复用中受益。
在2009年的时候,有两种不同的途径实现云端虚拟化:
- Amazon的EC2:用户几乎可以操控整个软件栈,包括内核。
- Google App Engine:在无状态计算层和有状态存储层之间强制使用分离的应用程序结构,App Engine 的自动扩展和高可用性机制。
市场选择了Amazon的EC2。文章作者猜测原因是部署方便,因为云端和本地的环境可以是一样的,不用重新为其需求重新写程序。但是这种做法也有缺陷,比如对虚拟机或者系统的维护,要知道这种做法对于小微企业是很困难的,他们没有足够的人力资源做到面面俱到,因此用户有了新需求:你设置一切,我只写代码。
于是在2015年,AWS开发了新的服务——AWS Lambda Service。现在就是我们常说的Faas,也就是无服务的核心。无服务计算的最初定义是不用服务器的计算,但是这压根是不可能的,没有服务器就无从计算,那这个名字是哪来的呢?主要还是为了解决“你设置一切,我只写代码”的需求,开发者不再为服务器怎么工作而担心,因此“无服务”这个名字就沿用了下来。
但是呢,有些特殊需求的程序要有后端的存在(抱歉,水平不够,不知道这种程序指哪些),于是AWS又提供了无服务框架“Baas(Backend as a service)”。
总之呢,现在的无服务计算(serverless computing)的标准化定义是:Faas+Baas。二者缺一不可。
无服务器计算的出现
文章解释了serverless和serverful的区别,将serverful比作低级编程语言如汇编,程序员需要指定寄存器完成相关操作,而serverless是高级语言,只需要完成逻辑不需要管寄存器的操纵。
准确的说,二者有以下三点主要不同:
- 解耦的计算与存储。存储和计算资源是分开提供的,相当于这两种资源的分配和计价都是独立的,通常来说存储资源是由一个独立的云服务来提供的,并且计算是无状态的。
- 不用管理资源分配的执行代码。除去要求的资源,云服务自动分配资源去执行代码。
- 以实际使用的资源付费而非分配的资源付费。比如用时间、占用的cpu核心数付费等等。
上图是无服务架构。
那么,要想真正的无服务成为可能,我们需要做哪些技术突破?
无服务的重点在于,更细粒度的服务管理。不同用户共享一套硬件设备,我们只有更细粒度,将时间、CPU运行核心,内存使用的大小等情况更细粒度的管理。同时,安全隔离也必须做到位。
无服务有哪些吸引人的点?最重要的肯定是节约成本,不用为额外的计算或者存储支出。此外,由于硬件的统一化,服务器不需要考虑前端兼容性,可以将服务器修改成更适合编程环境的指令集,以此加快程序运行速度。
如今无服务的限制
作者研究了五个不同的应用,并将它们与serverful相比较,看看性能是否匹配。
- ExCamera: 视频实时编码。现在的编码技术会将编码时间耗时在十几分钟甚至几小时,而利用ExCamera可以将编码和解码的耗时操作并行处理,非耗时操作串行处理。
- MapReduce:这块大家都熟悉,很经典的分布式应用,略
- Numpywren:线性代数计算。传统上,大规模线性代数计算部署在通过高速,低延迟网络连接的超级计算机或高性能计算集群上。 考虑到这一历史,无服务器计算最初似乎不合适。 但是,无服务器计算对于线性代数计算仍然有意义的原因有两个。 首先,对许多非CS科学家来说,管理集群是一大障碍。 其次,并行度的数量在计算过程中可能会发生巨大变化。 设置固定大小的群集会减慢工作速度,或者使群集使用不足。
- Cirrus:一种ML训练模型。同样,无服务可以将每个阶段所需要的资源进行扩展,提高利用率。
- Serverless SQLite:数据库。数据库难以进行无服务的原因是,无服务的服务都是利用虚拟化来实现对每个用户的服务,然而虚拟化不是永久性存储,我们又需要持久性存储,因此我们只能使用远程存储。远程存储将数据传给主机又会有网络延迟,会造成速度缓慢。此外,高性能数据库都依赖共享内存,但是云服务隔离内存,共享内存不太可能。最后,客户端传入连接可能与原有的云服务冲突,因此云服务又不支持传入连接。
下面作者提出了真正的无服务限制:
-
存储不足,无法提供细粒度操作。见表6,总结了一些存储的特性。
-
缺乏细粒度之间的协调。有协调就一定有要有通信机制,本身的无服务框架是没有消息通知机制的,但是服务商会提供消息通知服务,这种非内嵌的服务是耗时的,成本比较高。
-
标准通信模式的性能不佳。使用基于 VM 的解决方案,在同一个实例上运行的任务都可以共享数据广播的副本,或者在将部分结果发送到其他实例之前执行本地聚合,因此广播和聚合操作的通信复杂度为 O(N),其中 N 是系统中 VM 实例的数量。然而,对于云函数,这种复杂度为 O(NK),其中 K 是每个 VM 中的函数数量。这种操作在 shuffle 操作中更为显著,在基于 VM 的解决方案中,所有本地任务都可以组合它们的数据,这样两个 VM 实例之间就只有一条消息,假设发送方和接收方的数量相同,则产生 NN 条消息,对于云函数来说,我们需要发送 (NK)(N*K) 条消息,由于现有函数拥有的核数量比 VM 少的多,K 通常在 10 到 100 之间。因为应用程序无法控制云函数的位置,因此无服务计算应用可能需要发送比同等的基于 VM 的方法多 2-4 个数量级的数据。
上图是对Function-based和VM-based的模式比较。 -
性能可预测性。启动云虚拟机所需要的时间远远短于自己本地部署的虚拟机启动时间,但是启动加载云函数库需要几十倍的时间。这使得其性能不可预测。
无服务计算应该成为什么样?
-
抽象挑战:现在我们可以直接利用线程加速我们的程序执行,但是云服务时期,开发者只需要调用云函数,云函数是产品提供商写好的,这些服务根据数据量、服务类型判断程序需要的资源并分配,这就是高级别抽象。怎么做?从代码分析入手,重新编译等等方法进行代码重定向到其他的体系结构并执行。
数据依赖:云提供商公开一个 API 允许应用程序指定其计算图,从而实现更好的放置决策并最小化通信开销、提高性能。我们注意到,许多通用的分布式框架(如 MapReduce、Apache Spark 和 Apache Beam/CLoud Dataflow)、并行 SQL 引擎(例如 BigQuery、Azure Cosmos DB)以及编排框架(例如 Apache Airflow)已经在内部生成了这样的计算图。原则上可以修改这些系统,使其运行在云函数上,并将其计算图公开给云提供商。AWS Step Functions 通过提供状态机语言和 API 在往这个方向前进。 -
系统性挑战:这主要是存储挑战。
(1) 临时性存储(Ephemeral Storage):为无服务应用提供临时存储的一种方法是使用优化的网络栈构建分布式内存服务,以保证微秒级的延迟。该系统可以使应用的函数在其生命周期内有效地存储和交换,这样的内存服务需要根据应用程序的需求自动扩展存储容量和 IOPS。这样的服务独特之处在于,它不仅需要透明地分配内存,还需要透明地释放内存,特别是当应用终止或失败时,应该自动释放分配给该应用的存储。这种类似于操作系统在进程完成(或崩溃)时自动释放进程分配的资源,此外,这种存储必须提供跨应用的访问保护和性能隔离。
通过利用多路复用,这种临时存储可以比当今的 serverful 计算更节省内存,对于无服务计算,如果应用需要的内存少于分配的 VM 实例聚合的内存,那么这些内存就会被浪费,相反对于共享内存服务,一个无服务应用程序没有使用的内存都可以分配给另一个应用使用。事实上,多路复用甚至可以使单个应用程序受益:在 serverful 计算中,属于同一应用程序的运行在另一个 VM 上的程序不能使用 VM 未使用的内存,而在共享内存服务的情况下它可以。当然,即使没有无服务计算,如果云函数不使用它的整个本地内存,也可能存在内部碎片,在某些情况下,将云函数应用的状态存储在共享内存服务中可以减轻内存碎片化。
(2)持久性存储(Durable Storage):与其他应用程序一样,我们的无服务数据库应用受到存储系统的延迟和 IOPS 的限制,但它也需要长期的数据存储和文件系统的可变状态语义。虽然很可能数据库功能(包括 OLTP)将越来越多地座位 BaaS 提供,但是我们认为这个应用代表了好几种应用程序,这些应用程序需要比临时存储更长的保留时间和更强的持久性。要实现高性能的无服务持久性存储,一种方法是利用基于 SSD 的分布式存储和分布式内存缓存。最近的一个系统实现了这些目标,叫做 Anna key-value 数据库,它通过组合多个现有的云存储产品实现了成本效率和高性能,这种设计的一个关键挑战是在存在大量长尾访问分布的情况下实现低长尾延迟,因为内存缓存容量可能比 SSD 容量低得多。使用这种微秒级访问延迟的存储技术,正在成为解决这一挑战的办法。
与无服务临时存储类似,这种服务应该透明的提供并应确保应用程序和租户之间的隔离,以确保安全性和可预测的性能。然而,无服务临时性存储当应用终止时将回收资源,无服务持久性存储只能显示地释放资源(例如 “delete” 或 “remove” 命令),就像在传统的存储系统中,此外,它必须确保持久性,以便任何公认的写操作都能保证容错。(注:上述两点是拿来直接用的,没有加入个人见解。主要它说的这些我没有用过,也不好给见解,水平不够)
(3)协调服务(通讯服务):就是基础的通信,进程A和进程B要通信,通过框架内而不是框架外的支持更能减少通讯的代价。
(4) 最小化启动时间。 加载VM很轻松,但是加载云函数很吃力,因为云函数可以过于庞大。下载应用软件的运行时环境来运行函数代码(例如操作系统、库)也是耗时操作。我认为(是我不是论文作者)服务器可以长期维持一个大型云函数库,并一直在启动状态。有用户需求时直接从库中取,有新加的函数可以直接放进云函数库,这样可以减少启动时间,同时也可以分摊成本。当然,对部分用户可能是不公平的。 -
网络挑战:之前说的通讯模式,会使得通信的时间复杂度提升一量级,就是因为每个节点都要相互进行交流。有解决方法,如同:为云函数提供更多的 CPU 核。类似于 VM 实例,多个任务可以在通过网络发送数据之前或接收数据之后在这些核之间组合和共享数据;允许开发人员显示地将云函数放在同一个 VM 实例上。提供应用程序可以直接使用的分布式通信原语,以便云提供商可以将云函数分配给同一 VM 实例。这两种方法违背了serverless的原则。或者让应用程序提供一个计算图,使云提供商能够定位云函数,以最小化通信开销。
-
安全挑战:(不是做安全的,这方面我一点都不懂,略了)
-
计算机架构挑战:我们现在使用的都是x86系统架构,这个架构进步的太慢了(是不是厂家挤牙膏另说)。并且DRAM也接近满配,因此我们需要从硬件突破,设计出更适合云服务的架构。