AWS Lambda:"ELF load command address/offset not properly aligned" 通过无服务器框架部署时
AWS Lambda: "ELF load command address/offset not properly aligned" when deployed via Serverless Framework
我在 python3.6 中有一个使用以下包的 Lambda 函数:
opencv-python
imutils
numpy
joblib
mahotas
scikit-image
scikit-learn==0.22.1
sklearn
pymongo==3.10.1
我正在使用无服务器框架来最小化部署大小并部署到 lambda。我使用 serverless-python-requirements
插件来管理包。这是我的 template.yml 文件的样子:
functions:
hello:
handler: handler.hello
plugins:
- serverless-python-requirements
custom:
pythonRequirements:
dockerizePip: non-linux
zip: true
slim: true
noDeploy:
- boto3
- botocore
- docutils
- jmespath
- pip
- python-dateutil
- s3transfer
- setuptools
- six
- tensorboard
package:
exclude:
- node_modules/**
- model/**
- .vscode/**
我需要使用 slim
& zip
选项,否则部署包会太大 (~350mb)。
出于某种原因,如果我不在 requirements.txt
中包含 pymongo
,函数 运行 就可以了。不包含 pymongo
时 sls deploy
的输出是:
Serverless: Adding Python requirements helper...
Serverless: Generated requirements from /home/amman/Desktop/serverless-hello-world/requirements.txt in /home/amman/Desktop/serverless-hello-world/.serverless/requirements.txt...
Serverless: Using static cache of requirements found at /home/amman/.cache/serverless-python-requirements/3967fa669ece2345132bfe2a31be4287e2d61deedfb8b6006997a2192cea5753_slspyc ...
Serverless: Zipping required Python packages...
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Removing Python requirements helper...
Serverless: Injecting required Python packages to package...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service hello-world.zip file to S3 (128.52 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.........
Serverless: Stack update finished...
所以 .zip 的总大小约为 128 MB,函数 运行 没问题。但是,如果我包含 pymongo
,sls deploy
的输出是:
Serverless: Adding Python requirements helper...
Serverless: Generated requirements from /home/amman/Desktop/serverless-hello-world/requirements.txt in /home/amman/Desktop/serverless-hello-world/.serverless/requirements.txt...
Serverless: Installing requirements from /home/amman/.cache/serverless-python-requirements/279b0240a975ac6ad3c96e3b0ed81eec7981a8e66e0216037484878bfcaf4479_slspyc/requirements.txt ...
Serverless: Using download cache directory /home/amman/.cache/serverless-python-requirements/downloadCacheslspyc
Serverless: Running ...
Serverless: Zipping required Python packages...
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Removing Python requirements helper...
Serverless: Injecting required Python packages to package...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service hello-world.zip file to S3 (109.37 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.........
Serverless: Stack update finished...
现在大小减少到 ~109 MB。大小不应该因为我添加了新的依赖项而增加吗?当我 运行 lambda 函数时,出现错误:
Unable to import module 'handler': /tmp/sls-py-req/cv2/cv2.cpython-36m-x86_64-linux-gnu.so: ELF load command address/offset not properly aligned
我认为这可能是一个无服务器框架问题。我能做些什么来解决这个问题?我试过安装不同版本的 pymongo
但没有成功。
我正在使用以下无服务器框架版本:
> serverless --version
Framework Core: 1.73.1
Plugin: 3.6.13
SDK: 2.3.1
Components: 2.31.2
编辑:有没有pymongo的替代品?我见过一些,但他们使用 pymongo 作为底层依赖。
我无法用无服务器解决这个问题。所以我决定 sls deploy
没有 pymongo
并且一旦无服务器生成了 .requirements.zip
文件,我将该文件复制到其他地方并再次 运行 sls deploy
但这次只有pymongo
(和 pymongo[srv]
)在 requirements.txt
。生成的 .requirements.zip
包含 pymongo 及其依赖项。我合并了这个 .requirments.zip
的文件和第一个 sls deploy
生成的 requirements.zip
的文件。通过这种方式,我在一个 .requirements.zip
文件中获得了所有其他依赖项(opencv2、numpy、joblib 等)和 pymongo。
之后,我压缩了源代码和合并的 .requirements.zip
文件,并手动 将 zip 上传到 s3。压缩后为 128MB。指示我的 lambda 函数使用来自 S3 的这个部署包并且它起作用了。我得到了 pymongo 以及 opencv2 和其他依赖项。
但是,缺点是您必须上传到 S3 并自行更新功能。在这个问题得到解决之前,我将不得不使用这个“hack”。
使用图层。
单独打包函数。
lambda:
handler: lambda/handler.lambda_handler
runtime: python3.8
layers:
- {Ref: PythonRequirementsLambdaLayer}
package:
individually: true
...
pythonRequirements:
dockerizePip: non-linux
dockerImage: lambci/lambda:build-python3.8
layer: true
slim: true
slimPatterns:
# the commented ones are included in slim: true
# - '**/*.py[c|o]'
# - '**/__pycache__*'
# - '**/*.dist-info*'
- '**/*.egg-info*'
- '**/test/*'
- '**/tests/*'
invalidateCaches: true
我在 python3.6 中有一个使用以下包的 Lambda 函数:
opencv-python
imutils
numpy
joblib
mahotas
scikit-image
scikit-learn==0.22.1
sklearn
pymongo==3.10.1
我正在使用无服务器框架来最小化部署大小并部署到 lambda。我使用 serverless-python-requirements
插件来管理包。这是我的 template.yml 文件的样子:
functions:
hello:
handler: handler.hello
plugins:
- serverless-python-requirements
custom:
pythonRequirements:
dockerizePip: non-linux
zip: true
slim: true
noDeploy:
- boto3
- botocore
- docutils
- jmespath
- pip
- python-dateutil
- s3transfer
- setuptools
- six
- tensorboard
package:
exclude:
- node_modules/**
- model/**
- .vscode/**
我需要使用 slim
& zip
选项,否则部署包会太大 (~350mb)。
出于某种原因,如果我不在 requirements.txt
中包含 pymongo
,函数 运行 就可以了。不包含 pymongo
时 sls deploy
的输出是:
Serverless: Adding Python requirements helper...
Serverless: Generated requirements from /home/amman/Desktop/serverless-hello-world/requirements.txt in /home/amman/Desktop/serverless-hello-world/.serverless/requirements.txt...
Serverless: Using static cache of requirements found at /home/amman/.cache/serverless-python-requirements/3967fa669ece2345132bfe2a31be4287e2d61deedfb8b6006997a2192cea5753_slspyc ...
Serverless: Zipping required Python packages...
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Removing Python requirements helper...
Serverless: Injecting required Python packages to package...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service hello-world.zip file to S3 (128.52 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.........
Serverless: Stack update finished...
所以 .zip 的总大小约为 128 MB,函数 运行 没问题。但是,如果我包含 pymongo
,sls deploy
的输出是:
Serverless: Adding Python requirements helper...
Serverless: Generated requirements from /home/amman/Desktop/serverless-hello-world/requirements.txt in /home/amman/Desktop/serverless-hello-world/.serverless/requirements.txt...
Serverless: Installing requirements from /home/amman/.cache/serverless-python-requirements/279b0240a975ac6ad3c96e3b0ed81eec7981a8e66e0216037484878bfcaf4479_slspyc/requirements.txt ...
Serverless: Using download cache directory /home/amman/.cache/serverless-python-requirements/downloadCacheslspyc
Serverless: Running ...
Serverless: Zipping required Python packages...
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Removing Python requirements helper...
Serverless: Injecting required Python packages to package...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service hello-world.zip file to S3 (109.37 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.........
Serverless: Stack update finished...
现在大小减少到 ~109 MB。大小不应该因为我添加了新的依赖项而增加吗?当我 运行 lambda 函数时,出现错误:
Unable to import module 'handler': /tmp/sls-py-req/cv2/cv2.cpython-36m-x86_64-linux-gnu.so: ELF load command address/offset not properly aligned
我认为这可能是一个无服务器框架问题。我能做些什么来解决这个问题?我试过安装不同版本的 pymongo
但没有成功。
我正在使用以下无服务器框架版本:
> serverless --version
Framework Core: 1.73.1
Plugin: 3.6.13
SDK: 2.3.1
Components: 2.31.2
编辑:有没有pymongo的替代品?我见过一些,但他们使用 pymongo 作为底层依赖。
我无法用无服务器解决这个问题。所以我决定 sls deploy
没有 pymongo
并且一旦无服务器生成了 .requirements.zip
文件,我将该文件复制到其他地方并再次 运行 sls deploy
但这次只有pymongo
(和 pymongo[srv]
)在 requirements.txt
。生成的 .requirements.zip
包含 pymongo 及其依赖项。我合并了这个 .requirments.zip
的文件和第一个 sls deploy
生成的 requirements.zip
的文件。通过这种方式,我在一个 .requirements.zip
文件中获得了所有其他依赖项(opencv2、numpy、joblib 等)和 pymongo。
之后,我压缩了源代码和合并的 .requirements.zip
文件,并手动 将 zip 上传到 s3。压缩后为 128MB。指示我的 lambda 函数使用来自 S3 的这个部署包并且它起作用了。我得到了 pymongo 以及 opencv2 和其他依赖项。
但是,缺点是您必须上传到 S3 并自行更新功能。在这个问题得到解决之前,我将不得不使用这个“hack”。
使用图层。 单独打包函数。
lambda:
handler: lambda/handler.lambda_handler
runtime: python3.8
layers:
- {Ref: PythonRequirementsLambdaLayer}
package:
individually: true
...
pythonRequirements:
dockerizePip: non-linux
dockerImage: lambci/lambda:build-python3.8
layer: true
slim: true
slimPatterns:
# the commented ones are included in slim: true
# - '**/*.py[c|o]'
# - '**/__pycache__*'
# - '**/*.dist-info*'
- '**/*.egg-info*'
- '**/test/*'
- '**/tests/*'
invalidateCaches: true