
3.4 冷启动优化
“冷启动”这个现象常用于第一次执行操作,它在我们的生活中并不陌生,例如在第一次炒菜时需要热油、开汽车时需要等待汽车发动、在TCP第一次连接时需要三次握手等,可以说万事万物皆有冷启动。而在FaaS平台中,冷启动是不可忽视的一个特性,也是各大云服务商进行优化的主要方向。所谓“冷启动”,就是第一次部署函数,运行实例时,由于FaaS平台需要创建实例、部署网络,会有秒级别的较高延时。由于本地函数并不存在冷启动的概念,而云端函数的资源分配造成的冷启动则可能导致函数超时,对FaaS平台上的业务不够友好。因此,了解冷启动产生的原因以及优化措施,可以更好地理解FaaS平台原理,并进行有针对性的优化。
3.4.1 冷启动的产生
函数冷启动指的是FaaS函数在启动过程中的代码下载、启动实例、初始化运行时及用户代码等环节。
具体而言,FaaS函数在接收请求且没有空闲实例时,平台需要启动新的并发实例处理事件,该过程中并发实例创建和业务代码初始化引起的耗时都可以称为函数的冷启动耗时。
冷启动是怎样出现的呢?我们用一张图形象地展示在创建函数时,平台和用户分别负责哪些操作,从而分析冷启动的发生原理,如图3-4所示。

图3-4 冷启动的产生原因
根据上述执行流程可以看出,函数实例的启动过程主要分为两部分。
第一部分是启动函数实例,包含资源调度、下载客户提交的函数代码、启动初始化运行环境、加载运行代码。这一部分产生的耗时也叫作冷启动时间,主要由FaaS平台调度、执行和优化。
第二部分是函数的执行阶段,包含初始化代码、执行函数然后结束、退出执行环境。函数执行阶段主要由用户控制,根据业务及实现方式的不同,初始化和执行时间也不同,用户可以自行对这部分时间进行优化。
如图3-5所示,公有云FaaS平台上的冷启动主要分为以下几个过程。

图3-5 FaaS平台冷启动过程
- 创建虚拟机或容器:根据用户选择的配置,FaaS平台需要创建对应的运行环境。在不进行优化的情况下,该过程的平均耗时在秒级别,遇到极端情况时(需要创建新虚拟机或容器)甚至可能达到分钟级别。
- 函数代码包下载:该过程主要为运行环境加载用户的业务代码,代码包一般从对象存储等服务中获取,因此代码下载速度取决于业务代码包的大小,代码包较大时也会达到秒级别的耗时。
- 打通VPC(Virtual Private Cloud)等网络配置:FaaS平台不仅承担计算任务,当函数和其他资源,如外网服务、数据库等服务进行交互时,需要考虑打通私有网络和公网,这一步通常需要秒级别实现。
3.4.2 平台侧冷启动的优化
各大云厂商针对冷启动提供了各种优化策略,主要涉及以下三个方面。
1. 创建虚拟机和容器阶段
在该阶段,由于公有云平台的虚拟机调度系统需要满足更广泛的需求,难以针对FaaS场景做定制优化,因此各厂商相继推出了适用于FaaS平台的轻量级虚拟化系统(Micro VM),例如AWS Firecracker、Kata Container等。这些轻量级虚拟化系统主要针对镜像和驱动做了裁剪,使其更加轻量。此外,该系统将虚拟机的内存、设备状态等信息存储到共享内存,通过提前创建虚拟机模板文件,实现了极速启动和部署。
2. 代码包下载阶段
为了加速代码下载的速度,各云厂商通过代码缓存方案,将同账户下的代码缓存在本地节点作为一级缓存,多个可用区的代码也会作为二级缓存。
3. 打通网络配置阶段
在网络配置阶段,云厂商通过抽取网络转发层,将弹性网卡(Elastic Network Interface,ENI)绑定在转发层上,既可以复用网卡,又能降低绑定时间,提供高可用的架构。
虽然以上解决方案可以有效减少冷启动的概率,但依然难以100%避免冷启动,因此各商业化平台也提供了一些可配置的预留实例策略,通过提供常驻实例,降低服务延时。相信随着技术的持续进步,冷启动的问题将被更好地解决。
3.4.3 用户侧冷启动的规避
当前主流的冷启动规避方式为预置并发实例。从原理上讲,主要是通过预留实例的方式,有效规避冷启动的产生。但这也需要用户根据业务的具体场景,对不同函数的并发量进行预测、规划及合理分配。根据主流云厂商的产品限制,在对并发实例进行配置时,需要注意以下几点。
- 预置并发不支持$ LATEST最新版本,仅支持已发布的稳定版本。
- 可供配置的预置并发总数有限,一般会为账户/函数维度提供一个预置额度,需要用户根据账号下不同函数的使用情况进行合理分配。
- 由于预置并发需要额外的资源分配,因此计费方式可能有所不同。
- 并发实例处理完时间请求后,不会被立刻回收,而是会继续执行一段时间,以便于实例的复用。