在为 AWS Lambda 部署压缩虚拟环境时,我可以省略啥?

Posted

技术标签:

【中文标题】在为 AWS Lambda 部署压缩虚拟环境时,我可以省略啥?【英文标题】:When zipping a virtual env for AWS Lambda deployment, what can I leave out?在为 AWS Lambda 部署压缩虚拟环境时,我可以省略什么? 【发布时间】:2017-08-09 07:07:49 【问题描述】:

简介

我刚刚开始使用 AWS Lambda,尽管我讨厌它,但我非常喜欢它。我已经创建了a Makefile to help me 打包我的虚拟环境并发送到 S3。在我发现 cryptography 需要 hidden file in the site-packages directory #GRRR 后,我开始想知道如何进一步改进我的打包过程。

上下文

这就是新 Amazon Linux AMI EC2 实例上的新 virtualenv 的样子。

$ uname -srvm
Linux 4.4.51-40.58.amzn1.x86_64 #1 SMP Tue Feb 28 21:57:17 UTC 2017 x86_64

$ cat /etc/system-release
Amazon Linux AMI release 2016.09

$ virtualenv --version
15.1.0

$ pip --version
pip 9.0.1 from /usr/local/lib/python2.7/site-packages (python 2.7)

$ virtualenv temp
New python executable in /home/ec2-user/temp/bin/python2.7
Also creating executable in /home/ec2-user/temp/bin/python
Installing setuptools, pip, wheel...done.

图。 1

$ ls -a temp/lib/python2.7/site-packages/
.                        packaging-16.8.dist-info   setuptools-34.3.2.dist-info
..                       pip                        six-1.10.0.dist-info
appdirs-1.4.3.dist-info  pip-9.0.1.dist-info        six.py
appdirs.py               pkg_resources              six.pyc
appdirs.pyc              pyparsing-2.2.0.dist-info  wheel
easy_install.py          pyparsing.py               wheel-0.29.0.dist-info
easy_install.pyc         pyparsing.pyc
packaging                setuptools

图。 2

我发现为了做我需要的python开发(使用paramiko),我必须这样做准备(在图1和图2之前):

sudo yum install gcc python27-devel libffi-devel openssl-devel
sudo -H pip install --upgrade pip virtualenv

图。 3

问题

图中的那些站点包。 2,我可以从我发送到 AWS 的 zip 中省略哪些?

为了比较,这是我完整项目的 virtualenv 中的内容(我 pip 安装的唯一东西是 paramiko):

$ ls -a aws_lambda_project/lib/python2.7/site-packages/
.                             packaging
..                            packaging-16.8.dist-info
appdirs-1.4.3.dist-info       paramiko
appdirs.py                    paramiko-2.1.2.dist-info
appdirs.pyc                   pip
asn1crypto                    pip-9.0.1.dist-info
asn1crypto-0.22.0.dist-info   pkg_resources
cffi                          pyasn1
cffi-1.9.1.dist-info          pyasn1-0.2.3.dist-info
_cffi_backend.so              pycparser
cryptography                  pycparser-2.17.dist-info
cryptography-1.8.1.dist-info  pyparsing-2.2.0.dist-info
easy_install.py               pyparsing.py
easy_install.pyc              pyparsing.pyc
enum                          setuptools
enum34-1.1.6.dist-info        setuptools-34.3.2.dist-info
idna                          six-1.10.0.dist-info
idna-2.5.dist-info            six.py
ipaddress-1.0.18.dist-info    six.pyc
ipaddress.py                  wheel
ipaddress.pyc                 wheel-0.29.0.dist-info
.libs_cffi_backend

【问题讨论】:

是的,很好的问题,因为 virtualenv 非常庞大 - 所有这些膨胀(今天至少 22M)相当于 AWS Lambda 的成本。 【参考方案1】:

这对我有用,请试一试:

$ mkdir paramiko-lambda && cd paramiko-lambda
$ virtualenv env --python=python2.7 && source env/bin/activate
$ pip freeze > pre_paramiko.txt
$ pip install paramiko
$ pip freeze > post_paramiko.txt

然后我将以下内容放入脚本中以确保它在本地工作:

from __future__ import print_function
import paramiko


def handler(event, context):
    print(paramiko.__version__)
    ssh_client = paramiko.SSHClient()

if __name__ == '__main__':
    handler(event=None, context=None)

最后两行是可选的,只是在本地测试脚本的一种简单方法。为了查看与paramiko 一起安装的内容,我比较了两个文本文件:

$ diff -u pre_paramiko.txt post_paramiko.txt
--- pre_paramiko.txt
+++ post_paramiko.txt
@@ -1,4 +1,13 @@
 appdirs==1.4.3
+asn1crypto==0.22.0
+cffi==1.10.0
+cryptography==1.8.1
+enum34==1.1.6
+idna==2.5
+ipaddress==1.0.18
 packaging==16.8
+paramiko==2.1.2
+pyasn1==0.2.3
+pycparser==2.17
 pyparsing==2.2.0
 six==1.10.0

带有+ 的模块是使用paramiko 安装的,因此必须包含在上传到 AWS Lambda 的 .zip 存档中。编写一个 bash 脚本来获取 diff 命令的输出并自动创建 .zip 存档很容易,但我只是要手动输入它们。

$ cd env/lib/python2.7/site-packages
$ zip -x "*.pyc" -r ../../../../paramiko_lambda.zip packaging asn1crypto cffi cryptography enum idna ipaddress paramiko pyasn1 pycparser
$ cd ../../../../
$ zip -r paramiko_lambda.zip paramiko_lambda.py

我需要添加packaging 文件夹可能是因为print(paramiko.__version__),所以可能没有必要。 paramiko_lambda.zip 文件是 2.5 MB,虽然不是很大,但有很多不必要的数据,特别是 *.pyc 文件。排除 *.pyc 文件会将文件减少到 1.5 MB。

【讨论】:

这是个好主意。一旦有机会回到项目中,我会尽快尝试。 您知道包含*.pyc 文件是否有任何性能优势?也许在冷启动? 如果某个 lambda 函数在一段时间内保持空闲状态,AWS 将删除该容器。第一次执行时,AWS 创建容器时会有延迟。后续执行会更快,但这只是因为容器在内存中运行。请参阅here 了解有关 lambda 函数性能的更多信息,并参阅here 了解为什么 .pyc 并不比 .py 快。 这需要显式枚举 to 包含的文件,而不是应该排除的文件,因为每次添加新的依赖项时,您都需要修改 shell 脚本.

以上是关于在为 AWS Lambda 部署压缩虚拟环境时,我可以省略啥?的主要内容,如果未能解决你的问题,请参考以下文章

Serverless 在 Conda 虚拟环境中找不到我的 AWS 凭证是不是有原因?

来自执行环境的 AWS Lambda 凭证没有执行角色的权限

Lambda 在本地连接到 Aurora MySql - 部署到 AWS 时超时

部署lambda函数时AccessDeniedException

使用无服务器部署 AWS Lambda 函数在需要外部模块时不会部署

AWS Cloud9:一次只部署一个 Lambda 函数