使用 EMR Serverless 有几种方法可以做到这一点。无论您选择哪种方式,您都需要为 EMR Serverless StartJobRun 命令提供一个主入口点 Python 脚本。
注意:这必须使用与 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"
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 文件。
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 和 custom build outputs 将您的模块和依赖项打包到虚拟环境中。
注意:这需要您启用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 Serverless 作业(替换 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 的正确路径配置驱动程序和执行程序环境变量。