Как запустить проект (пакет) Python на бессерверном сервере AWS EMR?
У меня есть проект Python с несколькими модулями, классами и файлами зависимостей (файл
Проблема в том, что я не понимаю, как упаковать проект Python со всеми зависимостями, какой файл может использовать EMR и т. д. Во всех найденных мной примерах использовался один файл Python.
Проще говоря, что мне делать, если мой проект Python представляет собой не один файл, а более сложный?
1 ответ
Есть несколько способов сделать это с помощью EMR Serverless. Независимо от того, какой способ вы выберете, вам потребуется предоставить сценарий Python основной точки входа для команды EMR Serverless StartJobRun.
Предположим, у вас есть подобная структура заданий, где находится ваша точка входа, которая создает сеанс Spark и запускает ваши задания иjob1
иjob2
ваши локальные модули.
├── jobs
│ └── job1.py
│ └── job2.py
├── main.py
├── requirements.txt
Вариант 1. Использовать--py-files
с вашими заархивированными локальными модулями и с упакованной виртуальной средой для ваших внешних зависимостей
- Заархивируйте свои рабочие файлы
zip -r job_files.zip jobs
- Создайте виртуальную среду, используя
venv-pack
с вашими зависимостями.
Примечание. Это должно быть сделано с той же ОС и версией Python, что и EMR Serverless, поэтому я предпочитаю использовать многоэтапный файл 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 /
Если вы запустите , теперь у вас должен быть файл в вашей локальной системе.
Загрузить ,
job_files.zip
, и в расположение на S3.Запустите задание EMR без сервера с помощью такой команды (заменив , и ):
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 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
.