无服务器 Python 的 slim:true 参数对依赖项大小没有影响。

6

简介

当在serverless.yml中使用以下设置时:

custom:
  pythonRequirements:
    dockerizePip: true
    slim: true
    zip: true

slim:trueslim:false 会得到相同的文件大小。我该如何减小 zip 文件的大小?

完整内容

我正在使用 serverless 框架将 Python 代码及其依赖项部署到 AWS Lambda 函数中。为了满足 Lambda 250MB 的限制,我按照 此处 提供的建议来减少依赖项的大小。在我的 serverless.yml 文件中,我有以下内容:

provider:
  name: aws
  runtime: python3.6

plugins:
  - serverless-python-requierments

custom:
  pythonRequierments:
    dockerizePip: true
    slim: true
    zip: true

functions:
...

我的 requirements.txt 文件如下:

xgboost==1.3.3
pandas==1.0.1
numpy == 1.18.5
...

我不断地收到以下错误:
Unzipped size must be smaller than 262144000 bytes..

这让我相信我的requierments.zip文件太大了;冗长的输出显示uploading service test.zip file to s3 271.17 MB
我试着缩小文件大小,运行了sls deploy并将dockerizePipslim设置为false进行测试,但结果仍然是一个271.17MB的test.zip文件。这似乎很困惑,因为我理解slim:true应该在压缩文件之前减少文件大小,但是使用slim:trueslim:false运行得到的文件大小相同。我该如何让slim生效呢?
更新1:
我尝试添加一个slimPattern,如here所讨论,在pythonRequierments中。
slimPatterns:
  - '**/*.dist-info/**'

但是所有的dist信息目录仍然存在于zip文件中,输出的大小也相同(271.17MB)。
更新2:
我保留了从更新1中的所有内容,但是删除了.serverless目录和requierments.zip。所有的.dist-info目录仍然存在,尽管我在slimPatterns中排除了它们(或者我认为是这样)。
更新3:
我尝试使用包排除,做了以下操作:
package:
  exclude:
    -node_modules/**
    -'**/*.dist-info/**'

这确实成功地删除了node_modules(我本应该在之前就做的),但未成功以任何方式更改.requierments.zip,所有.dist-info目录保持不变。

更新4:

我按照 this 的方法,在pythonRequirements中添加了一个noDeploy字段,其中包括setuptoolssix。尽管如此,两者都出现在我的.requirements.zip文件中,我的文件大小没有改变(269.9 Mb,与更新3相同,由于删除了node_modules而稍微小了一些)

2个回答

4

我也碰到了同样的问题,最终我采用了以下选项来使用图层 -

custom:
  pythonRequirements:
    slim: true
    layer: true

我将部署包大小削减至不到10MB。所有依赖项都放在一个单独的ZIP文件中(约100MB),创建了Lambda Layer。这有助于减少Lambda冷启动问题。


1
对于未来的读者,我也使用了这个解决方案,它完美地运行了。相比于挂载EFS卷(当然这取决于您的使用情况),我更喜欢这个选项。 - Pramesh Bajracharya
我推荐这个解决方案适用于大多数情况,包括我的。您可以在此处阅读有关EFS与层以及其他方法的更多信息。在某些情况下,EFS可能仍然是更好的选择。 - Warlax56
解决方案没有起作用。解压的层超过了250MB,因此错误来自于层压缩而不是Lambda压缩包。 - ferk86

1

实际上,这个问题背后的概念是有缺陷的。这个问题的主要目的是如何将大型依赖项压缩到Lambda的大小限制中。最近,AWS为Lambda函数发布了EFS支持,这意味着您可以直接将卷挂载到Lambda函数上。这意味着几乎无限的存储空间,没有压缩要求,从而显著减少了冷启动时间。此外,这些文件系统可以挂载到多个Lambda函数。

我不会详细介绍,因为有很多事情要做,但如果您想在Lambda上获取大型依赖树,我建议您执行以下操作:

  • 创建一个VPC
  • 创建一个ec2实例
  • 创建一个EFS卷并将其挂载到您的ec2实例上
  • 通过pip install -r requierments.txt -t /mnt/.../efs/path将您的依赖项安装到efs实例上
  • 在serverless.yml中将该EFS实例挂载到您的lambda上
  • 通过将其附加到路径来将EFS卷上的模块添加到您的lambda函数中

在未来的几年里,Lambda函数的重点是运行小型、原子代码元素。如果您正在部署ML,只需设置类似Fargate或弹性Beanstalk的东西,并让它运行Python Docker容器即可。 - Warlax56

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