如何在 AWS EMR serverless 上运行 Python 项目(包)?

问题描述 投票:0回答:1

我有一个 Python 项目,其中包含多个模块、类和依赖文件(一个

requirements.txt
文件)。我想将它与所有依赖项一起打包到一个文件中,并将文件路径提供给 AWS EMR 无服务器,这将运行它。

问题是我不明白如何打包一个包含所有依赖项的 Python 项目,EMR 可以使用哪个文件等。我找到的所有示例都使用一个 Python 文件。

简单来说,如果我的Python项目不是单个文件而是比较复杂怎么办?

amazon-emr emr-serverless
1个回答
4
投票

有几种方法可以使用 EMR Serverless 做到这一点。无论您选择哪种方式,您都需要为 EMR Serverless StartJobRun 命令提供一个主要入口点 Python 脚本。

假设您有一个这样的工作结构,其中

main.py
是创建 Spark 会话并运行您的工作的入口点,
job1
job2
是您的本地模块。

├── jobs
│   └── job1.py
│   └── job2.py
├── main.py
├── requirements.txt

Option 1. 将
--py-files
与压缩的本地模块一起使用,
--archives
与用于外部依赖项的打包虚拟环境一起使用

  • 压缩你的工作文件
zip -r job_files.zip jobs
  • 使用
    venv-pack
    和您的依赖项创建一个虚拟环境。

注意:这必须使用与 EMR Serverless 类似的操作系统和 Python 版本来完成,因此我更喜欢使用带有自定义输出的多阶段 Dockerfile。

FROM --platform=linux/amd64 amazonlinux:2 AS base

RUN yum install -y python3

ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

COPY requirements.txt .

RUN python3 -m pip install --upgrade pip && \
    python3 -m pip install venv-pack==0.2.0 && \
    python3 -m pip install -r requirements.txt

RUN mkdir /output && venv-pack -o /output/pyspark_deps.tar.gz

FROM scratch AS export
COPY --from=base /output/pyspark_deps.tar.gz /

如果您运行

DOCKER_BUILDKIT=1 docker build --output . .
,您现在应该在本地系统上有一个
pyspark_deps.tar.gz
文件。

  • 上传

    main.py
    job_files.zip
    pyspark_deps.tar.gz
    到 S3 上的某个位置。

  • 使用这样的命令运行您的 EMR 无服务器作业(替换

    APPLICATION_ID
    JOB_ROLE_ARN
    YOUR_BUCKET
    ):

aws emr-serverless start-job-run \
    --application-id $APPLICATION_ID \
    --execution-role-arn $JOB_ROLE_ARN \
    --job-driver '{
        "sparkSubmit": {
            "entryPoint": "s3://<YOUR_BUCKET>/main.py",
            "sparkSubmitParameters": "--py-files s3://<YOUR_BUCKET>/job_files.zip --conf spark.archives=s3://<YOUR_BUCKET>/pyspark_deps.tar.gz#environment --conf spark.emr-serverless.driverEnv.PYSPARK_DRIVER_PYTHON=./environment/bin/python --conf spark.emr-serverless.driverEnv.PYSPARK_PYTHON=./environment/bin/python --conf spark.executorEnv.PYSPARK_PYTHON=./environment/bin/python"
        }
    }'

选项 2. 将您的本地模块打包为 Python 库,并使用
--archives
与打包的虚拟环境

这可能是最可靠的方法,但它需要您使用 setuptools。您可以使用一个简单的

pyproject.toml
文件以及现有的
requirements.txt

[project]
name = "mysparkjobs"
version = "0.0.1"
dynamic = ["dependencies"]
[tool.setuptools.dynamic]
dependencies = {file = ["requirements.txt"]}

然后您可以使用多阶段 Dockerfile 和 自定义构建输出 将您的模块和依赖项打包到虚拟环境中。

注意:这需要您启用Docker Buildkit

FROM --platform=linux/amd64 amazonlinux:2 AS base

RUN yum install -y python3

ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

WORKDIR /app
COPY . .
RUN python3 -m pip install --upgrade pip && \
    python3 -m pip install venv-pack==0.2.0 && \
    python3 -m pip install .

RUN mkdir /output && venv-pack -o /output/pyspark_deps.tar.gz

FROM scratch AS export
COPY --from=base /output/pyspark_deps.tar.gz /

现在您可以运行

DOCKER_BUILDKIT=1 docker build --output . .
并且将生成一个包含所有依赖项的
pyspark_deps.tar.gz
文件。将此文件和您的
main.py
脚本上传到S3。

假设您将两个文件都上传到

s3://<YOUR_BUCKET>/code/pyspark/myjob/
,像这样运行 EMR 无服务器作业(替换
APPLICATION_ID
JOB_ROLE_ARN
YOUR_BUCKET

aws emr-serverless start-job-run \
    --application-id <APPLICATION_ID> \
    --execution-role-arn <JOB_ROLE_ARN> \
    --job-driver '{
        "sparkSubmit": {
            "entryPoint": "s3://<YOUR_BUCKET>/code/pyspark/myjob/main.py",
            "sparkSubmitParameters": "--conf spark.archives=s3://<YOUR_BUCKET>/code/pyspark/myjob/pyspark_deps.tar.gz#environment --conf spark.emr-serverless.driverEnv.PYSPARK_DRIVER_PYTHON=./environment/bin/python --conf spark.emr-serverless.driverEnv.PYSPARK_PYTHON=./environment/bin/python --conf spark.executorEnv.PYSPARK_PYTHON=./environment/bin/python"
        }
    }'

注意额外的

sparkSubmitParameters
指定您的依赖项并配置驱动程序和执行程序环境变量以获得
python
.

的正确路径
© www.soinside.com 2019 - 2024. All rights reserved.