亚马逊AWS官方博客
AWS Lambda 中使用多线程解压 HAQM S3 大文件
当发布网页游戏时,通常会使用 HAQM Simple Storage Service(S3)来存放游戏中的静态资源。这些静态资源数量可达成千上万,如果直接从本地同步这么多文件到 S3,势必会花费较长的时间。
为了优化这个过程,我们可以考虑先将所有静态资源打包成一个 ZIP 文件,然后上传到 S3。ZIP 文件体积较小,上传速度会快很多。上传完成后,我们可以触发 AWS Lambda 服务,自动解压该 ZIP 文件,并将文件上传回指定的 S3。这种方式可以大大缩短发布网页游戏所需的时间。
在传统的 Lambda 自动解压方案中,解压后的上万个文件重新上传回 S3,使用单个线程需要消耗非常长的时间,甚至超过 Lambda 所能运行的最长时间(15 分钟)。您可以在 Lambda 使用多线程的运行,提高大文件解压上传的速度,最大可提高 30 倍,详细可参考文章后面的测试案例。
方案总览
在 S3 收到 zip 文件的上传后,S3 会触发 Lambda 进行下载并解压,解压完成后,通过 Goroutines 多线程的方式将解压后的文件上传到目标 S3 桶中。
![]() |
部署指南
点击链接 s3-zip-file-uncompress 在 AWS Serverless Application Repository 打开应用页面。输入用于存放解压后文件的 S3 存储桶名称,勾选确定该应用将创建相应的资源策略,点击 Deploy 按钮进行安装。
![]() |
注意:你可以改变对应的临时存储大小,但需要确保解压后,所有文件所占的空间小于该存储大小。由于 Lambda 目前最大支持的临时存储为 10GB,建议上传的 ZIP 文件不超过 3GB。根据业务需要调整 Lambda 的内存大小及并行执行的线程数量,建议使用默认线程数 100。
安装完成后,你可以在 AWS CloudFormation 的控制台页面中,选择对应的堆栈,并选中 Resources 查看到创建的 Lambda 函数。
![]() |
点击该 Lambda 函数链接进入到函数详细页面,通过点击 Add trigger 按钮增加触发器。
![]() |
在 Trigger configuration 页面中,选择 S3 为触发源并选择对应的用于上传 zip 文件的存储桶。Event types 中,选择 All object create events 并在 Suffix 中设置只有后缀为 .zip 的文件会触发事件,勾选须知并点击 Add 按钮进行添加。
![]() |
在设置触发配置完成以后,当往 S3 存储桶上传 zip 文件的时候,将会自动触发 Lambda 对该 zip 文件进行解压并上传到指定的 S3 中。
(可选)增加 Lambda 执行结果的主动通知。在 Lambda 函数页面中点击 Add destination 增加成功或失败时的消息推送。
![]() |
测试解压速度
上传大 zip 包进行测试,该 zip 包大小为 500M 并包含 1.3 万个小文件,Lambda 在分配 3G 内存时不同线程数设置下的执行时间对比。
![]() |
在线程数设置越高的情况下,Lambda 所执行的时间越短。同时,由于 Lambda 文件描述符的限制,在线程数超过 100 的情况下继续提高并不能获得更多的收益。
清理环境
为避免产生不必要的费用,在 CloudFormation 的 Stacks 中,选择对应的堆栈进行并点击 Delete。
![]() |
总结
在这篇文章中,您通过在 Serverless Application Repository 中安装应用,实现了对上传到 S3 中的大文件进行自动解压并上传到目标 S3 存储桶中的功能。在接收到 S3 的上传文件事件时将触发 Lambda 函数,它会启动多线程来加速解压和上传。通过 Lambda 的多线程处理,在大幅执行速度的同时也降低了 Lambda 的使用费用。