1.5 Serverless的挑战与机遇

2009年,加州大学伯克利分校的David Patterson等人总结了当时兴起的云计算的六大优点[5]

• 无限计算资源按需呈现。

• 用户无须承担对服务器的运维工作。

• 按照使用的计算资源付费。

• 借助超大型数据中心的规模效益大幅降低成本。

• 通过资源虚拟化简化运维,提高资源利用率。

• 通过复用来自不同组织的工作负载,提高硬件利用率。

2019年,加州大学伯克利分校在Cloud Programming Simplified: A Berkerley View on Serverless Computing[6]的回顾中总结到,当前的云平台在简化运维和提升硬件利用率上仍然无法让人满意。因为开发者还需要管理虚拟机的可靠性、负载均衡、容灾、扩容和缩容、监控、日志及系统升级,挑战仍然较大。尤其规模较小的企业,很难雇佣到熟练的运维或DevOps人员,无法通过自动化工具、脚本、服务来解决这些问题。

伯克利大学指出Serverless有望弥补这些不足。Serverless弱化了存储和计算之间的关系,使计算变得无状态、调度及扩容/缩容更容易、数据更安全。开发者不再需要手动创建虚拟机或管理其他资源(网络带宽等),只需要专注在业务代码开发上。同时,函数根据调用次数和每次计算的资源开销来计费,更加合理。

基于此,伯克利大学展望Serverless将会是未来云时代默认的计算范式。然而,当前的Serverless方兴未艾,为了让更多更广泛的应用基于其开发和运行,还需要解决一系列挑战。

• 函数生命周期有限,已加载的状态无法复用。当前主流的Serverless平台对函数的生命周期都有时间限制,函数不能长时间运行,只能在有限的时间内执行,如900s(15min)。当函数没有新的请求时,函数所在的执行环境被销毁,函数执行的中间状态、缓存等会被删除。当新的函数调用发起时,不能直接利用上次计算的缓存状态。

• 数据迁移成本高,影响运行效率。承载业务逻辑的函数在FaaS的容器上加载,独立于数据侧(BaaS)运行,函数执行时需要把数据运送到代码处,而不是把代码放在数据所在的计算节点上运行。对于大数据、分布式机器学习等场景,数据的迁移开销会影响这些工作负载的运行效率,同时也会给数据中心网络造成负担,从而限制Serverless的应用范围。虽然有类似S3的对象存储服务,但其数据迁移要比点对点通信速度慢、成本高。伯克利大学的研究表明,低速存储在视频转换、MapReduce、机器学习等场景下会影响细粒度调度、广播、聚合等的性能。此外,出于成本考虑,大多数Serverless服务是逻辑多租的(多个用户的函数在一个节点上执行),由于函数共享网络带宽,当运行的函数增多时,每个函数的带宽将成比例缩小,从而影响函数操作数据的性能。

• 启动性能不佳。提升冷启动性能是当前Serverless平台尚未解决的难题之一。以AWS Lambda平台为例,性能最好的是Node.js,1KB的代码量所需冷启动时间大约为200ms,而相同大小的Java应用所需冷启动时间则在600ms以上。函数的冷启动性能和语言、代码包的大小及沙箱调度的关系较大。代码包越大,冷启动时间越长(下载耗时)。此外,在冷启动时间中占比较大的部分是沙箱的冷启动时间,以Lambda为例,FireCracker的冷启动时间为125ms,占冷启动时间的60%。如果函数要连接到VPC内的数据库或服务上,则函数启动时还需要绑定ENI(弹性网络接口)来分配IP地址或连接VPC网关,这会进一步增加冷启动时间。目前,冷启动是将应用迁移到函数计算平台的一大障碍。例如,对App的SLA,某些移动应用要求端到端的冷启动时间小于300ms,如果切换到函数计算平台,考虑到中间的网络等待时间通常大于100ms,加上200ms的直接冷启动时间,总计时间无法满足SLA要求。虽然,目前有些函数计算平台通过预置实例和并发的方式来确保一定数量的函数实例热启动,但这类解决方案的成本较高,并不是最优的。

• 函数不可寻址,无法直接通信。当前函数实例无法互相看到IP地址,函数间通信时需要绕到外部来访问,导致通信时间较长。对于时间敏感的应用服务,如果存在级联的函数间请求,可能出现冷启动时间不达标的情况。而且,函数无法寻址也导致基于Serverless无法实现一致性算法,从而无法运行需要协商的分布式应用。

• 缺少异构硬件(如GPU/ARM等)支持。当前的Serverless平台允许用户指定配置包括CPU和RAM,但对于CPU和内存的分配是有限制的。大部分平台并不支持超高规格的资源,比如Lambda限制内存最大为10GB。对大数据或机器学习的应用来说,仅仅支持CPU和内存是不够的,这些场景需要更高的算力,必须使用GPU等异构硬件来加速模型训练,提升推理和预测的效率。函数规格的限制和GPU等硬件加速能力的缺失,影响了大数据和AI等新兴应用的Serverless化发展。另外,随着华为和AWS推出基于ARM的服务器实例,以及Apple推出基于ARM的PC,ARM生态的壮大意味着未来更多的服务可能基于ARM运行,因此Serverless也需要考虑对ARM的支持。

目前学术界和工业界已经出现一些新的系统,在尝试解决上述挑战,其中两个值得关注的项目是Faasm和CloudState。Faasm是一个基于轻量级隔离的有状态的Serverless函数计算平台,其论文作者认为当前的Serverless存在两个问题,即数据访问成本高(存储领域)及容器资源占用高(计算领域)。如前面所提到的,传输数据规模较大时需要借助外部存储服务,数据传输效率低;为了提升隔离性,使用轻量级虚拟机和容器,造成了资源浪费及启动性能损失。Faasm另辟蹊径,将容器替换为基于WebAssembly Runtime的Faaslets,既可保留轻量级隔离,又可提升启动性能。同时,为了减少数据迁移,Faasm设计实现了两级状态架构:同节点通过共享内存来访问,全局层面提供接口以进行跨节点访问。

虽然当前商用Serverless平台尚未将WebAssembly作为其运行时,也没有采取内置的两级数据存储机制来进行近数据计算,但从Faasm的尝试中不难看出,性能(函数启动时间、任务完成效率)及成本(数据迁移成本、函数实例容量)仍然存在很大的提升空间。

CloudState是Lightbend公司基于Knative推出的函数计算平台。该公司的创始人和CTO Jonas Bonér认为,当前的Serverless过于强调其在基础设施自动化方面的能力,适合应用在注重吞吐(需要扩展规模)或请求能在很短时间内完成的场景,缺乏构建和管理有状态应用的能力。他们认为需要支持有状态的Serverless实现,使其更高效地应用于以下场景。

• 机器学习训练和推理:模型需要在内存中动态替换,推理要保证低时延。

• 实时分布式流处理:如实时预测和推荐,以及异常检测。

• 用户会话、购物车、缓存:如管理跨请求、可缓存并可持久化的会话状态。

• 分布式事务工作流:如Saga模式、工作流编排、回滚和补偿等。

• 共享协作的工作空间:如文档协作编辑、聊天室等。

• 分布式系统选举:其他标准的分布式系统的协议协调的场景。

CloudState定义了用户函数和后端间的协议和规范,并基于Kubernetes生态的Knative、gRPC、Akka Cluster等实现了原型系统。CloudState的编程模型围绕状态数据来抽象,当前支持的模式包含事件溯源、CRDT(Conflict-Free Replicated Data Types)、Key-Value存储、P2P消息等。

Serverless编程模型的友好之处在于只抽象函数来承载业务逻辑,开发者不需要关注其他内容,因此CloudState也尝试用相同的方式抽象状态。对函数来说,请求响应可以与输入和输出的消息对应,那么状态的抽象也与之类似。如此,框架层就可以代表函数管理状态的持久化,监控状态的历史变化,做出更智能的决策。

CloudState通过Sidecar的方式实现了函数间直接通信,并且用类似Azure Function Data Bindings的方式接管状态数据的读写,从而可以支持多种一致性方式,为基于Serverless开发分布式应用提供更多选择,类似的实现还有Dapr。

此外,还有一些学术界的研究也在关注如何减少Serverless的数据迁移、优化冷启动性能等方面。例如,伯克利大学里斯实验室提出的CloudBurst,将分布式存储能力引入Serverless系统中,并且通过节点缓存减少数据迁移成本。上海交通大学提出的Catalyzer[7],基于Google的开源沙箱GVisor,通过沙箱状态复用及按需恢复函数状态来减少沙箱启动时间。鉴于篇幅所限,本节对学术界的更多探索不再展开赘述,有兴趣的读者可以关注相关学术会议的文献资料。