Snap Start

对于Lambda来说,初始化阶段需要下载函数代码、加载运行时和外部依赖, 又称为冷启动阶段。这个阶段虽然不会额外收费,但却为我们的函数执行带来了整体延迟。在第一次执行完后,Execution environment会保存一段时间,在这段时间内如果有后续的调用,则直接运行handler代码。

在某些Java环境里,Lambda的初始化阶段可能花10秒(如使用SprintBoot、Micronaut框架),在这个阶段里会做依赖注入、代码编译等工作。在为某个Lambda开启SnapStart后,重新发布新版本的代码会触发优化的流程,这个流程会运行整个Init阶段,然后创建一个不可变的、加密的快照,保存现场内存和磁盘,用于下一次重用(底层使用了 Firecracker 技术)。当函数被第二次调用时,直接从缓存取出状态来加载execution environment。因为不再需要经历初始化流程,所以会大大加快调用速度:

Diagram of a non-SnapStart function versus a SnapStart function

目前只支持Java Corretto(java11)运行时,可以让初始化的速度提高10倍。没有额外费用

SnapStart的整个生命周期如下:

SnapStart life cycle

测试

接下来使用Serverless Spring Boot 2 example 测试,未开启SnapStart时,在一开始的Init 阶段要6秒多:

img

开启SnapStart:

img

重新进行部署,进行测试:

img

使用SnapStart后,整个Init阶段只在初次发布新版本的时候运行。在后面调用Lambda时,只有 Restore duration + Duration过程,所以整个运行时间从6秒到降到了不到200ms。

由于SnapStart是一个快照,所以在开发代码时要考虑一些事项,比如

  • 如果初始化过程要下载一些三方数据,那么要保证三方数据不再更新,否则会产生数据不一致的情况。
  • 如果Init阶段生成了random seed用于加密,那么这个seed被缓存到快照里,每次代码执行都是一样的。

适用场景

目前SnapStart不支持ephemeral storage、EFSProvisioned ConcurrencyGraviton2。SnapStart适合通用场景,如果对延迟特别敏感,再考虑Provisioned Concurrency