AWS Python Lambda "Hello World" + psycopg2 依赖项 = 3.2 MB。我可以缩小吗?

AWS Python Lambda "Hello World" + psycopg2 dependency = 3.2 MB. Can I shrink?

我在 index.py:

中定义了一个简单的 python lambda 函数
def handler(event, context):
    return {"msg": "hello world. this is hello handler"}

通过 CDK(打字稿)部署:

const stack = new Stack(app, "PythonHelloStack", {env})
new PythonFunction(stack, `HelloFunction`, {
    runtime: Runtime.PYTHON_3_9,
    entry: path.join(__dirname, `../../../lambdas/hello`),
})

这有效,大小为 4.8 kB。伟大的。如果我将单个依赖项添加到 psycopg2-binary,而不更改 Python 代码,则 AWS Lambda 代码大小会从 4.8 kB 跃升至 3.2 MB。这是不可避免的还是有解决办法?我可以做些什么来减少代码大小吗?我是不是该?为此创建一个层是必要的还是有帮助的?有更简单的修复方法吗?谢谢:)

我的 psycopg2-binary 依赖项的项目具有以下 pyproject.toml:

[tool.poetry]
name = "hello"
version = "0.1.0"
description = ""
authors = []

[tool.poetry.dependencies]
python = "~3.9"
psycopg2-binary = "~2.9"

[tool.poetry.dev-dependencies]

[build-system]
requires = ["poetry-core>=1.1.0"]
build-backend = "poetry.core.masonry.api"

如果你创建一个安装了 PsycoPG2 的 v-env,你会发现这几乎是你可以摆脱的最低限度,因为轮子的组件及其依赖项的大小

虽然它不是 100% 与 2.9 相同,但这是我的 2.9.1 版本:

~/v-3.9/lib/python3.9/site-packages/psycopg2$ du -sh *
8.0K    __init__.py
140K    __pycache__
4.0K    _ipaddress.py
8.0K    _json.py
1.5M    _psycopg.cpython-39-x86_64-linux-gnu.so
20K     _range.py
16K     errorcodes.py
4.0K    errors.py
8.0K    extensions.py
44K     extras.py
8.0K    pool.py
16K     sql.py
8.0K    tz.py

注意共享对象的大小。您可能还想检查 import 语句 - 它们还引入了一些其他部分,这会导致您的代码大小增加。

好吧,首先psycopg2-binary and what binary是什么意思:

The binary packages come with their own versions of a few C libraries, among which libpq and libssl, which will be used regardless of other libraries available on the client

因此 psycopg2-binary 包括开箱即用的依赖项。因此,生成的 Lambda 层的大小相对较大。

正如您在上面 link 看到的,建议使用 psycopg2 包构建自己的库版本:

For production use you are advised to use the source distribution.

这将允许您使用较新的依赖库版本(libpqlibssl 等)。 psycopg2-binary 可能是很久以前构建的,可能已经过时或易受攻击。

关于你关于库大小的问题:即使你构建自己的 psycopg2 版本,它也会包含与预构建的 binary 相同数量的库,所以我不确定这里是否是能够经济合理的尺寸。

也可以查看这个documentation,不建议再使用二进制包:

The binary package is a practical choice for development and testing but in production it is advised to use the package built from sources.

此外,如果您决定构建库,此 answer 可能会有所帮助