减小Python zip文件大小以在AWS Lambda上使用

3

我正在遵循这篇博客文章,创建一个使用Docker的运行时环境,以便与AWS Lambda一起使用。我正在为Python 3.8创建一个层:

docker run -v "$PWD":/var/task "lambci/lambda:build-python3.8" /bin/sh -c "pip install -r requirements.txt -t python/lib/python3.8/site-packages/; exit"

然后将层存档为zip文件: zip -9 -r mylayer.zip python

到目前为止都是标准的步骤。问题出现在.zip文件的大小,它大于250mb,因此会在Lambda中创建以下错误:Failed to create layer version: Unzipped size must be smaller than 262144000 bytes

这里是我的requirements.txt

s3fs
scrapy
pandas
requests

我在使用pandas将parquet文件保存到S3存储桶时,遇到了以下错误:[ERROR] ImportError: Install s3fs to access S3。因此,我需要包含s3fs。但是这会导致镜像层的大小大大增加。如果不包含s3fs,则未解压缩的层数小于200MB。

我的问题是: 如何在仍使用Docker并保留requirements.txt中的s3fs的情况下,将镜像层大小减少到小于250MB? 我无法解释50MB+的差异,特别是在PyPis3fs的大小小于100KB。

最后,对于那些质疑我在Lambda中使用Scrapy的人:我的爬虫程序非常简单,启动EC2实例会过度消耗资源。


1
如果你有很多依赖项,容器 Lambda 是解决方案。你有 10GB 的依赖项空间。 - Marcin
感谢建议@Marcin - 我会看一下。目前,使用Python 3.6而不是3.8已经足够减小层大小了。 - mmz
当然。给我几分钟。 - Marcin
@mmz 看看我的答案,里面有一些建议可以帮助你进一步减小文件大小。 - rv.kvetch
2个回答

4

我无法解释这50MB+的差异,特别是因为PyPi上的s3fs < 100kb。

这很容易解释。如预期,s3fs在AWS库(在本例中是botocore)上有内部依赖。好消息是boto3已经包含在AWS Lambda中(请参见此链接以获取Lambda中可用的库),因此您可以从压缩的依赖项中排除botocore并节省总大小高达~50MB

有关更多信息,请参见上面的链接。您可以安全地从压缩的文件中删除以下库,并仍能够在运行Python 3.8的AWS Lambda函数上运行代码:

  • boto3 - 亚马逊 Web 服务 (AWS) 的软件开发工具包
  • botocore - 一个低级别的面向服务的客户端,用于 AWS 服务 API
  • docutils - 用于处理文档的工具集
  • jmespath - JSON 路径语言
  • pip - 用于安装和管理 Python 包的工具
  • python-dateutil (生成 dateutil 包) - 用于解析日期的工具集合
  • s3transfer - 用于 Amazon S3 的文件传输库
  • setuptools - 用于构建和分发 Python 包的工具
  • six (生成 six.py) - 使 Python 2 和 3 兼容性更好的工具模块
  • urllib3 (如果需要,可以删除捆绑在一起的依赖项,例如 chardet) - HTTP 请求库

您还可以使用 bash 脚本来递归地清除以下(垃圾)目录,这些目录您不需要:

  • __pycache__
  • *.dist-info (例如: certifi-2021.5.30.dist-info)
  • tests - 只有可能,但我不能确认。如果您选择递归地清除所有的tests文件夹,请首先检查在 lambda 上是否有任何破坏,因为在极少数情况下,这样的包可能会在代码中被导入。

做到这一点,您应该可以轻松地节省约60MB的压缩构件大小。

你是否有AWS Lambda已包含的那些库的参考文献? - ogdenkev
是的,应该在答案的链接中包含它。但无论如何,这里是参考链接:https://gist.github.com/gene1wood/4a052f39490fae00e0c3#file-all_aws_lambda_modules_python3-7-txt - rv.kvetch
对于 Python 3.8 运行时中的库,您只需进行文本搜索,查找列出了特定于 3.8 的库的帖子即可。 - rv.kvetch
二进制Wheel包怎么样 - 它们不是将文件“安装”到*.dist-info中吗? - Fredrik Wendt
@FredrikWendt 嗯,实际上我不太确定。你有一个安装文件到*.dist-info文件夹的包的例子吗? - rv.kvetch

3

缩减层的关键思想是确定哪些内容是pip安装的,哪些可以手动删除。

在您的情况下,由于您仅略高于限制,因此建议删除pandas/tests。因此,在创建zip层之前,您可以在该层文件夹(mylayer来自您以前的问题)中运行以下命令:

rm -rvf python/lib/python3.8/site-packages/pandas/tests

解压后,这应该能将您的图层剪裁到262MB以下。在我的测试中,现在是244MB

或者,您可以手动查看python文件夹,并开始删除不需要的任何其他测试,文档,示例等。


@mmz 没问题,很高兴能帮忙 :-) - Marcin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接