Lambda SnapStart 现已支持容器镜像

点击查看原文>

最近,亚马逊云科技将 Lambda SnapStart 的支持范围扩展到了以容器镜像形式打包的函数,从而消除了此前影响团队打包大型 Python 依赖项的权衡。容器镜像函数的最大容量可达 10 GB,而 ZIP 压缩包仅为 250 MB;但此前,选择容器就意味着必须放弃 SnapStart,并接受 Lambda 在下载镜像层和初始化运行时期间产生的为时数秒的启动延迟。

SnapStart 会在部署时对已经初始化的执行环境做快照,并将其缓存起来,然后在调用时从中恢复,而非从头开始初始化。亚马逊云科技表示,启动时间已经缩短至不到一秒。此前,该功能仅支持 Python、.NET 和 Java 的托管运行时。

在公告发布前一个月,该功能所要消除的限制已经在 Reddit 上的讨论中有所体现。一个在 Lambda 中运行 pandas 和 numpy 的团队描述称,他们曾经遇到 250 MB 的上限,不得不从自己的代码和已安装的包中删除空格、注释和文档字符串,从而节省了约 5 MB 的空间:

虽然使用容器确实解决了限制问题,但同时也去除了一个关键功能:SnapStart。

原帖作者指出,只有在没有任何地方调用 __doc__ 的情况下才能移除文档字符串,并反驳了关于重构架构的建议,称该代码是遗留代码,已经与技术栈紧密耦合,而且现实世界中确实存在技术债务。

该讨论帖纠正了一个常见的误解。两位评论者援引亚马逊云科技的文档证实,Lambda 层也会占用相同的 250 MB 解压后配额,因此,将 pandas 和 numpy 移入一个单独部署的层中并不能腾出空间。其中一人总结了团队面临的困境:

如果你需要保留 SnapStart 功能,一个变通方法是在初始化时挂载一个 EFS 访问点,并从那里导入大型库——虽然这样做需要忍受一次冷启动,但可以继续使用基于 ZIP 的 lambda。虽然去除空格和文档字符串的方法可行,但这意味着只要所依赖的版本一升级,你就会再次陷入困境。

该讨论帖中的大部分内容都认为问题出在工具本身,而非打包方式。有几位评论者建议使用 ECS Fargate、Step Functions 或 AWS Batch,理由是大量使用 pandas 的任务属于批处理性质,而 Lambda 并不适合此类场景。有人指出,在某些情况下,容器镜像函数的启动速度本就比 250 MB 的 zip 文件更快,在 SnapStart 出现之前就是这样。

这些论点依然成立。变化在于,那些因依赖项大小而选择容器的团队,不需要再为此付出启动性能的代价,这减少了仅因大小限制而被迫重构架构的情况。

不同基础镜像对该功能的支持情况不尽相同。对于搭载 Java 11 或更高版本、Python 3.12 或更高版本以及 .NET 8 或更高版本的 AWS 基础镜像,其使用体验与 ZIP 归档文件一致。其他任何镜像(包括 Node.js、Ruby 和自定义基础镜像)都必须在其 Dockerfile 中添加 LABEL com.amazonaws.lambda.feature.snapstart=“Allow”,或实现 SnapStart 运行时钩子。如果缺少其中任何一项,那么发布该版本时会在初始化阶段失败。

相关工具非常迅速地进行了跟进更新。在用户提交问题报告后,Serverless Framework 4.42.0 于公告发布一周内就推出了相关支持。一位维护者指出,在此次发布之前,对于已部署的基于镜像的函数设置 snapStart 其实就已经能够正常工作,这次是填补了剩余的空白:现在,框架会在部署前拒绝将临时存储大小设置为超过 512 MB 并与 SnapStart 同时启用的配置;此外,当容器函数发版失败时,系统会打印一条提示,指向标签或运行时钩子,而不是原始的 CloudFormation 消息。同一位维护者还指出,亚马逊云科技的 SnapStart 文档仍然停留在仅支持 Java 的时代。

这两种打包模型之间仍然存在一个区别。对于基于 ZIP 的函数,AWS 会为其运行时打补丁。而对于容器镜像,保持基础镜像处于最新状态则是客户的责任,SnapStart 并不会改变这一点。

除亚太区(新西兰)和台北以外,面向容器镜像的 SnapStart 已经在所有 AWS 商用区域内推出,用户可以通过 API、控制台、CLI、CloudFormation、SAM、SDK 和 CDK 在新函数或现有函数上启用该功能。亚马逊云科技将 SnapStart 的定价与标准 Lambda 定价在文档中分别做了说明。

原文链接:https://www.infoq.com/news/2026/09/lambda-snapstart-container-image/


本文来源:InfoQ