View a markdown version of this page

在 Amazon Glue 中使用 Python 虚拟环境 - Amazon Glue
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

在 Amazon Glue 中使用 Python 虚拟环境

自 Amazon Glue 5.0 起,您可以在 Python 虚拟环境(.venv)中运行 ETL 作业。使用虚拟环境后,无需在作业运行时解析依赖项,从而确保每次运行均使用相同的软件包,并防止上游软件包发生更改而导致故障。

Amazon Glue 支持两种使用虚拟环境的方式:

  • 服务生成的虚拟环境——在 Amazon Glue 6.0 及更高版本中可用。您添加 --python-virtual-env-storage-prefix 参数后,Amazon Glue 会为您构建虚拟环境,并将其缓存在 Amazon S3 中,供后续运行作业时使用。无需在本地构建。

  • 手动构建的虚拟环境——在 Amazon Glue 5.0 及更高版本中可用。您可以在本地计算机或 CI/CD 管道中构建虚拟环境,将其上传至 Amazon S3,然后通过 --python-virtual-env 参数引用该虚拟环境。

本主题介绍如何将使用 --additional-python-modules 的作业迁移到上述任一方式。有关管理 Python 依赖项的其他方法,请参阅 将 Python 库与 Amazon Glue 结合使用

与 --additional-python-modules 的主要区别

下表对 --additional-python-modules 与手动构建的虚拟环境进行了比较。

功能

--additional-python-modules

--python-virtual-env

基础容器库(boto3、numpy、pandas 及其他)

自动提供

不可用。您必须在 venv 中包含所有必需的软件包。

依赖关系解析

在运行时进行

在您的计算机上构建时进行

运行时隔离

部分。在基础库的基础上安装软件包。

完全。完全取代 Python 环境。

重要

迁移到 --python-virtual-env 时,必须在虚拟环境中包含作业所需的所有 Python 软件包。这包括以前可从 Amazon Glue 基础容器中获得的软件包,例如 boto3、numpy 和 pandas。这些软件包不再隐式可用。

选择方法

请参考下表,确定哪种方法适合您的作业。

场景

推荐方法

仅使用少量 pip 软件包且希望避免构建开销的简单作业

服务生成的 venv(添加 --python-virtual-env-storage-prefix)。需要 Amazon Glue 6.0 或更高版本。

复杂的依赖树、完全可重现性,或通过 CI/CD 管道构建 venv

手动构建的 venv(--python-virtual-env)。需要 Amazon Glue 5.0 或更高版本。

只需最少更改即可从 --additional-python-modules 迁移

服务生成的 venv(添加 --python-virtual-env-storage-prefix)。需要 Amazon Glue 6.0 或更高版本。在 Amazon Glue 5.0 和 5.1 上,请改用手动构建的虚拟环境。

包含自定义软件包的私有 PyPI 索引

两种方法均可。服务生成的 venv 需要 Amazon Glue 6.0 或更高版本,并且可与 --python-modules-installer-option 配合使用。

使用服务生成的虚拟环境及 Amazon S3 缓存

自 Amazon Glue 6.0 起,您可以使用 --python-virtual-env-storage-prefix 参数,让 Amazon Glue 构建虚拟环境并将其缓存到 Amazon S3 中。这种方法将 --additional-python-modules 的简单性与缓存虚拟环境的性能优势相结合。

工作原理

当您提供 --python-virtual-env-storage-prefix 时,Amazon Glue 会执行以下操作:

  • 首次运行(缓存未命中)——Amazon Glue 使用 --system-site-packages 创建虚拟环境,该环境会继承 numpy、pandas 和 pyarrow 等容器软件包。Amazon然后,Glue 使用 pip 安装 --additional-python-modules 中的软件包,将虚拟环境打包为 .tar.gz 文件,并将其上传至您的 Amazon S3 前缀,供后续重复使用。

  • 后续运行(缓存命中)——Amazon Glue 从 Amazon S3 下载并解压缓存的 .tar.gz 文件,然后配置 Spark 驱动程序和执行器使用该虚拟环境。无需进行 pip 安装。

与手动构建的虚拟环境的区别

下表对服务生成的虚拟环境与手动构建虚拟环境的方法进行了比较。

功能

服务生成的 venv

手动构建的 venv

构建职责

Amazon Glue 会自动构建 venv

您在 Docker 中构建 venv

容器软件包

通过 --system-site-packages 继承

必须显式包含所有软件包

首次运行延迟

需要额外时间进行 pip 安装、打包并上传至 Amazon S3

无,因为 venv 已预先构建

后续运行延迟

从 Amazon S3 下载并解压需要额外时间

从 Amazon S3 下载并解压需要额外时间

确定性

我们建议您锁定软件包版本

具有完全确定性,因为版本已在构建时锁定

PyPI访问

首次运行时需要

无需联网,因为 venv 已离线构建

配置服务生成的虚拟环境

--python-virtual-env-storage-prefix 参数用于指定 Amazon Glue 存储其所构建虚拟环境的 Amazon S3 位置,格式为 s3://path/。AmazonGlue 在首次运行作业时将虚拟环境缓存到此前缀,并在后续运行中重复使用。

要启用服务生成的虚拟环境,请将 --python-virtual-env-storage-prefix 参数添加到您的作业中,并保留现有的 --additional-python-modules 参数。

"--additional-python-modules": "requests==2.32.3,scikit-learn==1.5.0" "--python-virtual-env-storage-prefix": "s3://amzn-s3-demo-bucket/venv-cache/"

您还可以使用以下可选参数:

  • --python-virtual-env-version —— 缓存虚拟环境的版本标识符。更改此值可使缓存失效,并强制 Amazon Glue 重新构建虚拟环境。该值是一个字符串,因此您可以采用适合自身工作流的任意版本控制方案,例如递增编号、日期或构建标识符。默认值为 0

  • --python-modules-installer-option —— 向 pip 传递选项,例如 --no-deps--index-url

要为现有作业启用缓存,请添加存储前缀参数。首次运行耗时较长,因为 Amazon Glue 需要构建并上传虚拟环境;后续运行则会使用缓存的虚拟环境,无需进行 pip 依赖项解析。

# Before "--additional-python-modules": "requests==2.32.3" # After "--additional-python-modules": "requests==2.32.3" "--python-virtual-env-storage-prefix": "s3://amzn-s3-demo-bucket/venv-cache/"

Amazon Glue 如何缓存虚拟环境

Amazon Glue 根据作业配置生成缓存键。配置包括 --additional-python-modules 中的模块、--python-modules-installer-option 的值、Amazon Glue 版本以及 --python-virtual-env-version 的值。

配置未发生变化时,即可命中缓存。如果您更改上述任意值,Amazon Glue 将构建新的虚拟环境并创建新的缓存条目。

Amazon Glue 将每个缓存的虚拟环境分别存储在存储前缀下的独立键中。使用相同模块和安装程序选项的作业共享相同的缓存条目。

限制

  • 需要 Amazon Glue 6.0 或更高版本。

  • 首次运行时需要访问 PyPI 或您的私有索引,以便进行依赖项解析。

  • 系统会继承 numpy 和 pandas 等容器软件包,但不会锁定其版本。如果您的作业需要使用特定版本的容器软件包,请改用 --python-virtual-env

  • 缓存键由配置决定。更改任何模块或版本都会创建新的缓存条目;先前的缓存条目会一直保留在 Amazon S3 中,直至您将其删除。

自行构建虚拟环境

在 Amazon Glue 5.0 及更高版本中,您可以自行构建虚拟环境,并使用 --python-virtual-env 参数引用该虚拟环境。如果您要求环境完全可重现、需要使用特定版本的容器软件包,或者需要通过 CI/CD 管道执行构建,请使用此方法。

先决条件

开始之前,请确保已具备以下条件:

  • 从 Docker 网站获取并安装在本地计算机上的 Docker,以便您能够在与 Amazon Glue 兼容的环境中构建虚拟环境

  • 用于上传已打包虚拟环境的 Amazon S3 存储桶

  • 已配置相应权限的 Amazon CLI,可用于上传至 Amazon S3 并更新 Amazon Glue 作业参数

有关每个 Amazon Glue 版本的 Python 版本和平台兼容性详情,请参阅 附录 B:Amazon Glue 环境详细信息

第 1 步:创建 requirements 文件

创建两个 requirements 文件,用于指定虚拟环境所需的软件包。

  1. 从 GitHub 网站上的 aws-glue-libs 存储库下载适用于您的 Amazon Glue 版本的 base-requirements.txt。此文件列出了标准 Amazon Glue 容器提供的软件包。要查看本指南中的同一列表,请参阅 Amazon Glue 中已提供的 Python 模块

  2. 创建additional-requirements.txt。将现有 --additional-python-modules 参数中的软件包逐行添加,每行一个。例如:

    cryptography requests-oauthlib sqlalchemy
重要

如果您的作业使用 Amazon Glue Python 库(例如 GlueContextDynamicFrame),则还必须添加 PyPI 网站上提供的 AWSGlueDataplanePython 软件包。请按照下表,使用与您的 Amazon Glue 版本相匹配的软件包版本。

Amazon Glue 版本

软件包版本

5.0

AWSGlueDataplanePython==5.0.0

5.1

AWSGlueDataplanePython==5.1.0

6.0

AWSGlueDataplanePython==6.0.0

步骤 2:创建 Dockerfile

创建一个与目标 Amazon Glue 版本的运行环境相匹配的 Dockerfile。有关平台和 Python 版本的详细信息,请参阅 附录 B:Amazon Glue 环境详细信息

AmazonGlue 5.0 和 5.1 在 Amazon Linux 2023 上使用 Python 3.11。

FROM --platform=linux/amd64 public.ecr.aws/amazonlinux/amazonlinux:2023-minimal RUN dnf install -y python3.11 zip && \ dnf clean all WORKDIR /build

AmazonGlue 6.0 在 Amazon Linux 2023 上使用 Python 3.13。

FROM --platform=linux/amd64 public.ecr.aws/amazonlinux/amazonlinux:2023-minimal RUN dnf install -y python3.13 zip && \ dnf clean all WORKDIR /build

步骤 3:构建并启动容器

构建 Docker 镜像。然后启动一个容器,并将 requirements 文件和作业脚本挂载到该容器中。

docker build --platform linux/amd64 -t glue-venv-builder . docker run --platform linux/amd64 \ -v $(pwd)/base-requirements.txt:/working_dir/base-requirements.txt:ro \ -v $(pwd)/additional-requirements.txt:/working_dir/additional-requirements.txt:ro \ -v $(pwd)/my_glue_script/:/working_dir/my_glue_script/:ro \ -v $(pwd):/output \ -w /working_dir \ -it glue-venv-builder bash

此命令会挂载您的 requirements 文件以及 Amazon Glue 作业脚本目录。下一步将使用该脚本目录进行导入分析。

第 4 步:构建临时 venv 并确定所需的软件包

在容器内,构建一个与 Amazon Glue 运行时环境相匹配的临时 venv。然后使用静态分析确定作业所需的最小软件包集合。

对于使用 Python 3.11 的 Amazon Glue 5.0 和 5.1,请运行以下命令。

# Create a temporary venv to reproduce the Amazon Glue runtime environment python3.11 -m venv temp_venv source temp_venv/bin/activate python3.11 -m pip install --upgrade pip # Install base container libraries (mirrors what the Amazon Glue container provides) python3.11 -m pip install -r base-requirements.txt # Install additional Python modules on top (mirrors how Amazon Glue installs them at runtime) python3.11 -m pip install -r additional-requirements.txt # Freeze the full resolved environment pip freeze > full-requirements.txt # Install analysis tools python3.11 -m pip install pipreqs pip-tools # Use pipreqs to discover what the script actually imports # --mode no-pin outputs package names without versions pipreqs --mode no-pin --savepath discovered-requirements.txt /working_dir/my_glue_script # Remove packages provided by the Spark runtime sed -i '/pyspark/d' discovered-requirements.txt sed -i '/py4j/d' discovered-requirements.txt # Remove awsglue - install AWSGlueDataplanePython in Step 5 instead sed -i '/awsglue/d' discovered-requirements.txt # Use pip-compile to resolve the full dependency tree of the discovered packages, # constrained to the versions from the temporary venv pip-compile discovered-requirements.txt -c full-requirements.txt -o final-requirements.txt echo "=== Final requirements.txt ===" cat final-requirements.txt # Deactivate and discard the temporary venv deactivate rm -rf temp_venv

对于使用 Python 3.13 的 Amazon Glue 6.0,请运行以下命令。

# Create a temporary venv to reproduce the Amazon Glue runtime environment python3.13 -m venv temp_venv source temp_venv/bin/activate python3.13 -m pip install --upgrade pip # Install base container libraries (mirrors what the Amazon Glue container provides) python3.13 -m pip install -r base-requirements.txt # Install additional Python modules on top (mirrors how Amazon Glue installs them at runtime) python3.13 -m pip install -r additional-requirements.txt # Freeze the full resolved environment pip freeze > full-requirements.txt # Install analysis tools python3.13 -m pip install pipreqs pip-tools # Use pipreqs to discover what the script actually imports # --mode no-pin outputs package names without versions pipreqs --mode no-pin --savepath discovered-requirements.txt /working_dir/my_glue_script # Remove packages provided by the Spark runtime sed -i '/pyspark/d' discovered-requirements.txt sed -i '/py4j/d' discovered-requirements.txt # Remove awsglue - install AWSGlueDataplanePython in Step 5 instead sed -i '/awsglue/d' discovered-requirements.txt # Use pip-compile to resolve the full dependency tree of the discovered packages, # constrained to the versions from the temporary venv pip-compile discovered-requirements.txt -c full-requirements.txt -o final-requirements.txt echo "=== Final requirements.txt ===" cat final-requirements.txt # Deactivate and discard the temporary venv deactivate rm -rf temp_venv
注意

检查 final-requirements.txt,确认其内容正确无误。如果您的作业使用动态导入或条件导入,pipreqs 可能无法检测到这些导入。手动将这些软件包添加到文件中。

第 5 步:构建生产环境 venv

创建最终的 venv,其中仅包含作业所需的软件包。然后将其打包成 tarball 文件。

对于使用 Python 3.11 的 Amazon Glue 5.0 和 5.1,请运行以下命令。

python3.11 -m venv pyspark_venv source pyspark_venv/bin/activate python3.11 -m pip install --upgrade pip python3.11 -m pip install -r final-requirements.txt # Install the Amazon Glue Python library that matches your Amazon Glue version (see the version # table in Step 1). Use 5.0.0 for Amazon Glue 5.0, or 5.1.0 for Amazon Glue 5.1. python3.11 -m pip install AWSGlueDataplanePython==5.0.0 python3.11 -m pip install venv-pack venv-pack -f -o pyspark_venv.tar.gz cp pyspark_venv.tar.gz /output/ exit

对于使用 Python 3.13 的 Amazon Glue 6.0,请运行以下命令。

python3.13 -m venv pyspark_venv source pyspark_venv/bin/activate python3.13 -m pip install --upgrade pip python3.13 -m pip install -r final-requirements.txt # Install the Amazon Glue Python library (see version table in Step 1) python3.13 -m pip install AWSGlueDataplanePython==6.0.0 python3.13 -m pip install venv-pack venv-pack -f -o pyspark_venv.tar.gz cp pyspark_venv.tar.gz /output/ exit

步骤 6:上传到 Amazon S3

将打包后的虚拟环境上传至您的 Amazon S3 存储桶。

aws s3 cp pyspark_venv.tar.gz s3://amzn-s3-demo-bucket/path/pyspark_venv.tar.gz

第 7 步:更新作业参数

更新您的 Amazon Glue 作业配置,改用 --python-virtual-env,不再使用 --additional-python-modules

移除 --additional-python-modules 参数,然后添加 --python-virtual-env 参数,并使其指向您已上传的 tarball 文件。

# Before "--additional-python-modules": "cryptography" # After (remove --additional-python-modules entirely) "--python-virtual-env": "s3://amzn-s3-demo-bucket/path/pyspark_venv.tar.gz"

使用 Kiro 实现迁移自动化

如果您倾向于采用自动化方式,可以使用 Kiro 网站上提供的 Kiro,从命令行执行 自行构建虚拟环境 中所述的迁移。使用 Kiro 技能后,Kiro 会分析您的 Amazon Glue 作业配置,在 Docker 中构建虚拟环境,并生成打包好的 tarball 文件。

工作原理

当您让 Kiro 将您的 Amazon Glue 作业从 --additional-python-modules 迁移到 --python-virtual-env 时,Kiro 将执行以下操作:

  1. 从您的请求中提取 Amazon Glue 版本、--additional-python-modules 的值和作业脚本。

  2. 从 Amazon Glue 文档中检索适用于您的 Amazon Glue 版本的基础容器模块列表。

  3. 在工作目录中创建构建构件,包括 base-requirements.txtadditional-requirements.txt、Dockerfile 和构建脚本。

  4. 为与 Amazon Glue 兼容的环境构建 Docker 镜像。

  5. 在非交互式容器中运行发现与打包工作流。

  6. 生成 pyspark_venv.tar.gz,提示您指定 Amazon S3 目标位置,然后上传 tarball 文件。

  7. 显示更新后的作业参数。

示例请求

提供您的 Amazon Glue 版本、额外的 Python 模块以及作业脚本。例如:

I have a Glue 5.1 job with the following: --additional-python-modules: ephem, awscli Glue job script: import awscli import ephem Help me migrate to using --python-virtual-env.

获取 Kiro 技能

venv-migration 技能文件在 aws-glue-libs 存储库中维护,本指南不提供该文件。有关技能文件及安装说明,请参阅 GitHub 网站上的 venv-migration 技能

限制

  • 使用 Kiro 时,命令行环境中必须提供 Docker。

  • 系统无法自动检测脚本源代码中未明确显示的动态导入和条件导入。检查生成的 final-requirements.txt 文件,并手动添加缺失的软件包。

  • 如果您的作业使用带有 --index-url 的私有 pip 索引,则必须在 Docker 容器中配置该索引的网络访问权限。

  • 构建期间出现的 pip 冲突可能需要手动解决。有关更多信息,请参阅 问题排查

问题排查

请参阅以下各节,解决在 Amazon Glue 中使用 Python 虚拟环境时遇到的常见问题。

解决 pip 版本冲突

pip 版本冲突是指两个软件包要求同一依赖项使用彼此不兼容的版本。要查找并修复冲突,请执行以下操作:

  1. 查看 pip 错误输出。解析彻底失败时,输出会列出每项相互冲突的依赖项要求,以及引入该要求的软件包。

  2. 在不安装任何内容的情况下,预览 pip 的依赖项解析结果。按照以下示例,将 --dry-run --report install-report.json 添加到安装命令中。

    pip install -r additional-requirements.txt --dry-run --report install-report.json
  3. 检查install-report.json 该报告会列出 pip 选择的所有软件包,从而显示其中是否存在静默降级。

  4. 放宽对非关键软件包的版本锁定,或移除相关约束。

解决 ModuleNotFoundError

此错误表示您的虚拟环境中缺少必需的软件包。常见原因包括以下各项:

  • 您未包含作业所需的基础容器库。手动构建的虚拟环境不会继承 Amazon Glue 容器中的软件包。

  • 您的作业使用了 pipreqs 在静态分析期间无法检测到的动态导入。

  • 作业的执行器节点需要 PySpark 依赖项。

要解决此问题,请添加缺失的软件包并重建虚拟环境。具体步骤取决于您的作业所采用的方法。

  • 手动构建 venv —— 将软件包添加到 final-requirements.txt,然后重新构建虚拟环境并再次上传。

  • 服务生成的 venv —— 将软件包添加到 --additional-python-modules。新的模块列表会更改缓存键,因此 Amazon Glue 会在下一次运行作业时构建新的虚拟环境。

减小 venv tarball 文件的大小

如果打包后的虚拟环境过大,请采用以下方法减小其大小:

  • 移除脚本未导入的非必要软件包,例如测试框架和开发工具。

  • 对于需要手动控制传递依赖项的软件包,请使用 pip install --no-deps

  • 仅包含脚本直接导入的软件包,并让 pip-compile 解析最低限度的必要传递依赖项。

解决平台兼容性错误

如果 venv 中的软件包是针对其他操作系统或系统架构构建的,就会出现此类错误。为避免此类错误,请执行以下操作:

  • 始终使用 --platform linux/amd64 标志在 Docker 容器内构建虚拟环境。

  • 确认 wheel 平台标签与目标 Amazon Glue 版本相匹配。例如,Amazon Glue 5.0 和 5.1 需要 manylinux2014_x86_64 或兼容的平台标签。

  • 如果没有 Docker,请勿直接在 macOS 或 Windows 上构建虚拟环境。