Как запустить проект (пакет) Python на бессерверном сервере AWS EMR?

У меня есть проект Python с несколькими модулями, классами и файлами зависимостей (файлфайл). Я хочу запаковать его в один файл со всеми зависимостями и дать путь к файлу AWS EMR serverless, который его запустит.

Проблема в том, что я не понимаю, как упаковать проект 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.

Другие вопросы по тегам