Dataproc サーバーレス用 Spark でカスタム コンテナを使用する

Dataproc Serverless for Spark は、Docker コンテナ内でワークロードを実行します。コンテナは、ワークロードのドライバとエグゼキュータのプロセス用のランタイム環境を提供します。Dataproc Serverless for Spark のデフォルトでは、ランタイム リリース バージョンに関連付けられたデフォルトの Spark、Java、Python、R パッケージを含むコンテナ イメージを使用します。Dataproc Serverless for Spark バッチ API を使用すると、デフォルトのイメージの代わりにカスタム コンテナ イメージを使用できます。通常、カスタム コンテナ イメージは、デフォルトのコンテナ イメージで提供されていない Spark ワークロードの Java または Python の依存関係を追加します。重要: カスタム コンテナ イメージには Spark を使用しないでください。Dataproc Serverless for Spark は、実行時に Spark をコンテナにマウントします。

カスタム コンテナ イメージを使用して Spark バッチ ワークロードを送信する

gcloud

Spark バッチ ワークロードを送信するときに、--container-image フラグを指定して gcloud dataproc batchs submit spark コマンドを使用し、カスタム コンテナ イメージを指定します。

gcloud dataproc batches submit spark \
    --container-image=custom-image, for example, "gcr.io/my-project-id/my-image:1.0.1" \
    --region=region \
    --jars=path to user workload jar located in Cloud Storage or included in the custom container \
    --class=The fully qualified name of a class in the jar file, such as org.apache.spark.examples.SparkPi \
    -- add any workload arguments here

注:

  • カスタム イメージ: Container Registry イメージ命名形式 {hostname}/{project-id}/{image}:{tag} を使用して、カスタム コンテナ イメージを指定します(例: gcr.io/my-project-id/my-image:1.0.1)。注: カスタム コンテナ イメージは Container Registry または Artifact Registry でホストする必要があります (Dataproc Serverless は他のレジストリからコンテナを取得できません)。
  • --jars: カスタム コンテナ イメージに含まれているか、または Cloud Storage に配置されているユーザー ワークロードへのパス(file:///opt/spark/jars/spark-examples.jar または gs://my-bucket/spark/jars/spark-examples.jar など)を指定します。
  • その他の batch コマンド オプション: 永続履歴サーバー(PHS)を使用する場合などは、他のオプションの batch コマンド フラグを追加できます。注: PHS は、バッチ ワークロードを実行するリージョンに配置する必要があります。
  • ワークロード引数 - ワークロード引数を追加するには、コマンドの末尾に「--」を付加し、その後にワークロード引数を追加します。

REST

カスタム コンテナ イメージは、batches.create API リクエストの一部として RuntimeConfig.containerImage フィールドを介して提供されます。

次の例は、Dataproc Serverless for Spark batches.create API を使用してバッチ ワークロードを送信するために、カスタム コンテナを使用する方法を示しています。

リクエストのデータを使用する前に、次のように置き換えます。

  • project-id: Google Cloud プロジェクト ID
  • region: リージョン
  • custom-container-image: Container Registry イメージ命名規則 {hostname}/{project-id}/{image}:{tag} を使用して、カスタム コンテナ イメージを指定します(例: gcr.io/my-project-id/my-image:1.0.1)。注: カスタム コンテナは Container Registry または Artifact Registry でホストする必要があります。 (Dataproc Serverless は他のレジストリからコンテナを取得できません)。
  • jar-uri: カスタム コンテナ イメージに含まれている、または Cloud Storage にあるワークロード jar のパスを指定します(例: /opt/spark/jars/spark-examples.jar、gs:///spark/jars/spark-examples.jar)。
  • class: jar ファイル内のクラスの完全修飾名(例: org.apache.spark.examples.SparkPi)。
  • sparkBatch.args フィールドを使用して、ワークロードに引数を渡すことができます(詳細については、Batch リソースのドキュメントをご覧ください)。永続履歴サーバー(PHS)を使用するには、永続的な履歴サーバーの設定をご覧ください。 注: PHS は、バッチ ワークロードを実行するリージョンに配置する必要があります。

HTTP メソッドと URL:

POST https://dataproc.googleapis.com/v1/projects/project-id/locations/region/batches

リクエストの本文(JSON):

{
  "runtimeConfig":{
    "containerImage":"custom-container-image
  },
  "sparkBatch":{
    "jarFileUris":[
      "jar-uri"
    ],
    "mainClass":"class"
  }
}

リクエストを送信するには、次のいずれかのオプションを展開します。

次のような JSON レスポンスが返されます。

{
"name":"projects/project-id/locations/region/batches/batch-id",
  "uuid":",uuid",
  "createTime":"2021-07-22T17:03:46.393957Z",
  "runtimeConfig":{
    "containerImage":"gcr.io/my-project/my-image:1.0.1"
  },
  "sparkBatch":{
    "mainClass":"org.apache.spark.examples.SparkPi",
    "jarFileUris":[
      "/opt/spark/jars/spark-examples.jar"
    ]
  },
  "runtimeInfo":{
    "outputUri":"gs://dataproc-.../driveroutput"
  },
  "state":"SUCCEEDED",
  "stateTime":"2021-07-22T17:06:30.301789Z",
  "creator":"account-email-address",
  "runtimeConfig":{
    "properties":{
      "spark:spark.executor.instances":"2",
      "spark:spark.driver.cores":"2",
      "spark:spark.executor.cores":"2",
      "spark:spark.app.name":"projects/project-id/locations/region/batches/batch-id"
    }
  },
  "environmentConfig":{
    "peripheralsConfig":{
      "sparkHistoryServerConfig":{
      }
    }
  },
  "operation":"projects/project-id/regions/region/operation-id"
}

カスタム コンテナ イメージを構築する

Dataproc Serverless for Spark のカスタム コンテナ イメージは Docker イメージです。Docker イメージをビルドするツールを使用してカスタム コンテナ イメージを作成できますが、イメージが Dataproc Serverless for Spark との互換性を満たさなければならないという条件があります。以下のセクションでは、これらの条件について説明します。

オペレーティング システム

カスタム コンテナ イメージのベース イメージとして、任意のオペレーティング システムを選択できます。

推奨: 互換性の問題を回避するテストが実施されているため、デフォルトの Debian 12 イメージ(debian:12-slim など)を使用します。

ユーティリティ

Spark の実行に必要な次のユーティリティ パッケージを、カスタム コンテナ イメージに含める必要があります。

  • procps
  • tini

Spark(Java または Scala)から XGBoost を実行するには、libgomp1 を含める必要があります。

コンテナ ユーザー

Dataproc Serverless for Spark は、1099 UID と 1099 GID を使用して spark Linux ユーザーとしてコンテナを実行します。カスタム コンテナ イメージの Dockerfile で設定された USER ディレクティブは、実行時に無視されます。ファイル システムの権限には、UID と GID を使用します。たとえば、イメージ内の /opt/spark/jars/my-lib.jar に jar ファイルを追加する場合は、spark ユーザーにファイルの読み取り権限を付与する必要があります。

イメージ ストリーミング

Dataproc Serverless for Spark は、通常、イメージ全体をディスクにダウンロードして、カスタム コンテナ イメージを必要とするワークロードを開始します。 これにより、特にイメージのサイズが大きい場合、初期化に遅延が生じることがあります。

代わりに、必要に応じて画像データを pull する方法である画像ストリーミングを使用できます。これにより、イメージ全体がダウンロードされるのを待たずにワークロードを起動できるため、初期化時間が改善される可能性があります。イメージ ストリーミングを有効にするには、Container File System API を有効にする必要があります。また、コンテナ イメージを Artifact Registry に保存する必要があり、Artifact Registry リポジトリは、Dataproc ワークロードと同じリージョン、またはワークロードが実行されているリージョンに対応するマルチリージョンに存在する必要があります。Dataproc がイメージをサポートしていない場合、またはイメージ ストリーミング サービスが利用できない場合は、ストリーミング実装によってイメージ全体がダウンロードされます。

なお、イメージ ストリーミングの場合、以下はサポートされていません。

このような場合、Dataproc はワークロードを開始する前にイメージ全体を pull します。

Spark

カスタム コンテナ イメージに Spark を含めないでください。Dataproc Serverless for Spark は、実行時にホストから Spark バイナリと構成ファイルをコンテナにマウントします。バイナリは /usr/lib/spark ディレクトリにマウントされ、構成ファイルは /etc/spark/conf ディレクトリにマウントされます。これらのディレクトリ内の既存のファイルは、実行時に Dataproc Serverless for Spark によってオーバーライドされます。

Java ランタイム環境

カスタム コンテナ イメージに独自の Java Runtime Environment(JRE)を含めないでください。Dataproc Serverless for Spark は、実行時にホストから OpenJDK をコンテナにマウントします。カスタム コンテナ イメージに JRE を含めても無視されます。

Java パッケージ

カスタム コンテナ イメージに Spark ワークロードの依存関係として jar ファイルを含めることができ、jar を含めるように SPARK_EXTRA_CLASSPATH 環境変数を設定できます。Dataproc Serverless for Spark は、Spark JVM プロセスのクラスパスに環境変数値を追加します。おすすめの方法: jar を /opt/spark/jars ディレクトリに配置し、SPARK_EXTRA_CLASSPATH/opt/spark/jars/* に設定します。

カスタム コンテナ イメージにワークロード jar を含めて、ワークロードの送信時にローカル パスでそのワークロード jar を参照できます(例: file:///opt/spark/jars/my-spark-job.jar。例については、カスタム コンテナ イメージを使用して Spark バッチ ワークロードを送信するをご覧ください)。

Python パッケージ

デフォルトでは、Dataproc Serverless for Spark は、実行時にホストからコンテナ内の /opt/dataproc/conda ディレクトリに Conda をマウントします。PYSPARK_PYTHON/opt/dataproc/conda/bin/python に設定されています。そのベース ディレクトリ /opt/dataproc/conda/binPATH に含まれています。

Python 環境をカスタム コンテナ イメージ内の別のディレクトリ(/opt/conda など)のパッケージに含めて、PYSPARK_PYTHON 環境変数を /opt/conda/bin/python に設定できます。

カスタム コンテナ イメージには、Python 環境に含まれない他の Python モジュール(ユーティリティ関数を含む Python スクリプトなど)を含めることができます。モジュールが配置されているディレクトリを含めるように PYTHONPATH 環境変数を設定します。

R 環境

次のいずれかのオプションを使用して、カスタム コンテナ イメージ内の R 環境をカスタマイズできます。

  • Conda を使用して、conda-forge チャンネルから R パッケージを管理してインストールします。
  • コンテナ イメージの Linux OS 用に R リポジトリを追加し、Linux OS パッケージ マネージャーを使用して R パッケージをインストールします(R Software パッケージのインデックスをご覧ください)。

どちらのオプションを使用する場合でも、カスタム R 環境を指すように R_HOME 環境変数を設定する必要があります。例外: R 環境の管理と Python 環境のカスタマイズの両方を行うために Conda を使用している場合、R_HOME 環境変数を設定する必要はありません。それは PYSPARK_PYTHON 環境変数に基づいて自動的に設定されます。

カスタム コンテナ イメージのビルド例

このセクションでは、カスタム コンテナ イメージのビルド例を示します。サンプルの Dockerfiles と、その後にビルドコマンドを示します。1 つのサンプルには、イメージのビルドに必要な最小構成が含まれています。他のサンプルには、Python ライブラリや R ライブラリなど、追加の構成の例が含まれています。

最小構成

# Recommendation: Use Debian 12.
FROM debian:12-slim

# Suppress interactive prompts
ENV DEBIAN_FRONTEND=noninteractive

# Install utilities required by Spark scripts.
RUN apt update && apt install -y procps tini libjemalloc2

# Enable jemalloc2 as default memory allocator
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2

# Create the 'spark' group/user.
# The GID and UID must be 1099. Home directory is required.
RUN groupadd -g 1099 spark
RUN useradd -u 1099 -g 1099 -d /home/spark -m spark
USER spark
    

追加の構成

# Recommendation: Use Debian 12.
FROM debian:12-slim

# Suppress interactive prompts
ENV DEBIAN_FRONTEND=noninteractive

# Install utilities required by Spark scripts.
RUN apt update && apt install -y procps tini libjemalloc2

# Enable jemalloc2 as default memory allocator
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2

# Install utilities required by XGBoost for Spark.
RUN apt install -y procps libgomp1

# Install and configure Miniconda3.
ENV CONDA_HOME=/opt/miniforge3
ENV PYSPARK_PYTHON=${CONDA_HOME}/bin/python
ENV PATH=${CONDA_HOME}/bin:${PATH}
ADD https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh .
RUN bash Miniforge3-Linux-x86_64.sh -b -p /opt/miniforge3 \
  && ${CONDA_HOME}/bin/conda config --system --set always_yes True \
  && ${CONDA_HOME}/bin/conda config --system --set auto_update_conda False \
  && ${CONDA_HOME}/bin/conda config --system --set channel_priority strict
# Packages ipython and ipykernel are required if using custom conda and want to
# use this container for running notebooks.
RUN ${CONDA_HOME}/bin/mamba install ipython ipykernel

# Install Conda packages.
#
# The following packages are installed in the default image.
# Recommendation: include all packages.
#
# Use mamba to quickly install packages.
RUN ${CONDA_HOME}/bin/mamba install -n base \
    accelerate \
    bigframes \
    cython \
    deepspeed \
    evaluate \
    fastavro \
    fastparquet \
    gcsfs \
    google-cloud-aiplatform \
    google-cloud-bigquery-storage \
    google-cloud-bigquery[pandas] \
    google-cloud-bigtable \
    google-cloud-container \
    google-cloud-datacatalog \
    google-cloud-dataproc \
    google-cloud-datastore \
    google-cloud-language \
    google-cloud-logging \
    google-cloud-monitoring \
    google-cloud-pubsub \
    google-cloud-redis \
    google-cloud-spanner \
    google-cloud-speech \
    google-cloud-storage \
    google-cloud-texttospeech \
    google-cloud-translate \
    google-cloud-vision \
    langchain \
    lightgbm \
    koalas \
    matplotlib \
    mlflow \
    nltk \
    numba \
    numpy \
    openblas \
    orc \
    pandas \
    pyarrow \
    pynvml \
    pysal \
    pytables \
    python \
    pytorch-cpu \
    regex \
    requests \
    rtree \
    scikit-image \
    scikit-learn \
    scipy \
    seaborn \
    sentence-transformers \
    sqlalchemy \
    sympy \
    tokenizers \
    transformers \
    virtualenv \
    xgboost

# Install pip packages.
RUN ${PYSPARK_PYTHON} -m pip install \
    spark-tensorflow-distributor \
    torcheval

# Install R and R libraries.
RUN ${CONDA_HOME}/bin/mamba install -n base \ 
    r-askpass \
    r-assertthat \
    r-backports \
    r-bit \
    r-bit64 \
    r-blob \
    r-boot \
    r-brew \
    r-broom \
    r-callr \
    r-caret \
    r-cellranger \
    r-chron \
    r-class \
    r-cli \
    r-clipr \
    r-cluster \
    r-codetools \
    r-colorspace \
    r-commonmark \
    r-cpp11 \
    r-crayon \
    r-curl \
    r-data.table \
    r-dbi \
    r-dbplyr \
    r-desc \
    r-devtools \
    r-digest \
    r-dplyr \
    r-ellipsis \
    r-evaluate \
    r-fansi \
    r-fastmap \
    r-forcats \
    r-foreach \
    r-foreign \
    r-fs \
    r-future \
    r-generics \
    r-ggplot2 \
    r-gh \
    r-glmnet \
    r-globals \
    r-glue \
    r-gower \
    r-gtable \
    r-haven \
    r-highr \
    r-hms \
    r-htmltools \
    r-htmlwidgets \
    r-httpuv \
    r-httr \
    r-hwriter \
    r-ini \
    r-ipred \
    r-isoband \
    r-iterators \
    r-jsonlite \
    r-kernsmooth \
    r-knitr \
    r-labeling \
    r-later \
    r-lattice \
    r-lava \
    r-lifecycle \
    r-listenv \
    r-lubridate \
    r-magrittr \
    r-markdown \
    r-mass \
    r-matrix \
    r-memoise \
    r-mgcv \
    r-mime \
    r-modelmetrics \
    r-modelr \
    r-munsell \
    r-nlme \
    r-nnet \
    r-numderiv \
    r-openssl \
    r-pillar \
    r-pkgbuild \
    r-pkgconfig \
    r-pkgload \
    r-plogr \
    r-plyr \
    r-praise \
    r-prettyunits \
    r-processx \
    r-prodlim \
    r-progress \
    r-promises \
    r-proto \
    r-ps \
    r-purrr \
    r-r6 \
    r-randomforest \
    r-rappdirs \
    r-rcmdcheck \
    r-rcolorbrewer \
    r-rcpp \
    r-rcurl \
    r-readr \
    r-readxl \
    r-recipes \
    r-recommended \
    r-rematch \
    r-remotes \
    r-reprex \
    r-reshape2 \
    r-rlang \
    r-rmarkdown \
    r-rodbc \
    r-roxygen2 \
    r-rpart \
    r-rprojroot \
    r-rserve \
    r-rsqlite \
    r-rstudioapi \
    r-rvest \
    r-scales \
    r-selectr \
    r-sessioninfo \
    r-shape \
    r-shiny \
    r-sourcetools \
    r-spatial \
    r-squarem \
    r-stringi \
    r-stringr \
    r-survival \
    r-sys \
    r-teachingdemos \
    r-testthat \
    r-tibble \
    r-tidyr \
    r-tidyselect \
    r-tidyverse \
    r-timedate \
    r-tinytex \
    r-usethis \
    r-utf8 \
    r-uuid \
    r-vctrs \
    r-whisker \
    r-withr \
    r-xfun \
    r-xml2 \
    r-xopen \
    r-xtable \
    r-yaml \
    r-zip

ENV R_HOME=/usr/lib/R

# Add extra Python modules.
ENV PYTHONPATH=/opt/python/packages
RUN mkdir -p "${PYTHONPATH}"

# Add extra jars.
ENV SPARK_EXTRA_JARS_DIR=/opt/spark/jars/
ENV SPARK_EXTRA_CLASSPATH='/opt/spark/jars/*'
RUN mkdir -p "${SPARK_EXTRA_JARS_DIR}"

#Uncomment below and replace EXTRA_JAR_NAME with the jar file name.
#COPY "EXTRA_JAR_NAME" "${SPARK_EXTRA_JARS_DIR}"

# Create the 'spark' group/user.
# The GID and UID must be 1099. Home directory is required.
RUN groupadd -g 1099 spark
RUN useradd -u 1099 -g 1099 -d /home/spark -m spark
USER spark
      

ビルドコマンド

Dockerfile ディレクトリで次のコマンドを実行して、カスタム イメージをビルドし、Artifact Registry に push します。

# Build and push the image.
gcloud builds submit --region=REGION \
    --tag REGION-docker.pkg.dev/PROJECT/REPOSITORY/IMAGE_NAME:IMAGE_VERSION