Benutzerdefinierte Container mit Dataproc Serverless für Spark verwenden

Dataproc Serverless for Spark führt Arbeitslasten in Docker-Containern aus. Der Container stellt die Laufzeitumgebung für die Treiber- und Executor-Prozesse der Arbeitslast bereit. Standardmäßig verwendet Dataproc Serverless for Spark eine Container-Image, das die standardmäßigen Spark-, Java-, Python- und R-Pakete enthält die mit einer Laufzeitversion verknüpft ist. Serverloses Dataproc für Spark Batches Mit der API können Sie ein benutzerdefiniertes Container-Image anstelle des Standard-Images verwenden Bild. In der Regel fügt ein benutzerdefiniertes Container-Image Spark-Arbeitslast Java oder Python hinzu. Abhängigkeiten, die nicht vom Standard-Container-Image bereitgestellt werden. Wichtig:Vermeiden Sie es, Fügen Sie Spark in Ihr benutzerdefiniertes Container-Image ein. In Dataproc Serverless for Spark wird Spark bereitgestellt zur Laufzeit in den Container.

Spark-Batcharbeitslast mit einem benutzerdefinierten Container-Image senden

gcloud

Verwenden Sie die Methode gcloud Dataproc Batches Senden von Spark Befehl mit dem Flag --container-image, um Ihr benutzerdefiniertes Container-Image anzugeben wenn Sie eine Spark-Batcharbeitslast senden.

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

Hinweise:

  • Custom-Image: Geben Sie das benutzerdefinierte Container-Image mithilfe der Methode im folgenden Namensformat für Container Registry-Images: {hostname}/{project-id}/{image}:{tag}, Beispiel: „gcr.io/my-project-id/my-image:1.0.1“. Hinweis: Sie müssen Ihr benutzerdefiniertes Container-Image auf Container Registry oder Artifact Registry Dataproc Serverless kann keine Container aus anderen Registrys abrufen.
  • --jars:Geben Sie einen Pfad zu einem Nutzerarbeitslast, die in Ihrem benutzerdefinierten Container-Image enthalten ist oder sich in Cloud Storage befindet, z. B. file:///opt/spark/jars/spark-examples.jar oder gs://my-bucket/spark/jars/spark-examples.jar.
  • Weitere Optionen für Batches:Sie können weitere optionale Batches hinzufügen. Befehls-Flags. Beispiel: um einen Persistent History Server (PHS) zu verwenden. Hinweis: Der PHS muss sich in der Region befinden, in der Sie Batcharbeitslasten ausführen.
  • Arbeitslastargumente Sie können beliebige Arbeitslastargumente durch Hinzufügen des Befehls „--“ hinzufügen. bis das Ende des Befehls, gefolgt von den Arbeitslastargumenten.

REST

Das benutzerdefinierte Container-Image wird über das Feld RuntimeConfig.containerImage im Rahmen einer batches.create-API-Anfrage bereitgestellt.

Im folgenden Beispiel sehen Sie, wie Sie mit einem benutzerdefinierten Batcharbeitslast mit Dataproc Serverless für Spark senden batches.create verwenden.

Ersetzen Sie diese Werte in den folgenden Anfragedaten:

  • project-id: ID des Google Cloud-Projekts.
  • region: Region
  • custom-container-image: Geben Sie das benutzerdefinierte Container-Image mithilfe der Methode im folgenden Namensformat für Container Registry-Images: {hostname}/{project-id}/{image}:{tag}, Beispiel: „gcr.io/my-project-id/my-image:1.0.1“. Hinweis: Der benutzerdefinierte Container muss auf folgendem Gerät gehostet werden: Container Registry oder Artifact Registry . Dataproc Serverless kann keine Container aus anderen Registrys abrufen.
  • jar-uri: Geben Sie einen Pfad zur Arbeitslast-JAR-Datei an, die in Ihrem benutzerdefinierten Container-Image enthalten ist oder sich in Cloud Storage befindet. Beispiel: "/opt/spark/jars/spark-examples.jar" oder "gs:///spark/jars/spark-examples.jar".
  • class: Der voll qualifizierte Name einer Klasse in der JAR-Datei, z. B. „org.apache.spark.examples.SparkPi“.
  • Weitere Optionen: Sie können andere Batch-Ressourcenfelder für Arbeitslasten verwenden, z. B.: verwenden Sie die sparkBatch.args zur Übergabe von Argumenten an Ihre Arbeitslast (siehe die Batch finden Sie in der Ressourcendokumentation. Um eine Persistent History Server (PHS) Siehe Nichtflüchtigen Verlaufsserver einrichten Hinweis: Der PHS muss sich in der Region befinden, in der Sie Batcharbeitslasten ausführen.

HTTP-Methode und URL:

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

JSON-Text anfordern:

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

Wenn Sie die Anfrage senden möchten, maximieren Sie eine der folgenden Optionen:

Sie sollten in etwa folgende JSON-Antwort erhalten:

{
"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"
}

Benutzerdefiniertes Container-Image erstellen

Dataproc Serverless für benutzerdefinierte Spark-Container-Images sind Docker-Images. Sie können Verwenden Sie die Tools zum Erstellen von Docker-Images, um benutzerdefinierte Container-Images zu erstellen, aber es gibt Bedingungen, die die Images erfüllen müssen, um mit Dataproc Serverless für Spark kompatibel zu sein. In den folgenden Abschnitten werden diese Bedingungen erläutert.

Betriebssystem

Sie können ein beliebiges Betriebssystem-Image als Basis-Image für Ihr benutzerdefiniertes Container-Image auswählen. Empfehlung: Die Debian 11-Standard-Images werden bevorzugt, z. B. debian:11-slim. da sie getestet wurden, um Kompatibilitätsprobleme zu vermeiden.

Dienstprogramme

Sie müssen die folgenden erforderlichen Dienstprogrammpakete hinzufügen um Spark in Ihrem benutzerdefinierten Container-Image auszuführen:

  • procps
  • tini

Zum Ausführen von XGBoost aus Spark (Java oder Scala) müssen Sie libgomp1

Containernutzer

Bei Dataproc Serverless for Spark werden Container als spark-Linux-Nutzer mit der UID 1099 und der GID 1099 ausgeführt. USER-Anweisungen in benutzerdefinierten Container-Image-Dockerfiles festgelegt werden während der Laufzeit ignoriert. Verwenden Sie die UID und die GID für Dateisystemberechtigungen. Wenn Sie beispielsweise im Bild unter /opt/spark/jars/my-lib.jar eine JAR-Datei hinzufügen Arbeitslastabhängigkeit müssen Sie dem spark-Nutzer die Leseberechtigung -Datei.

Image-Streaming

Dataproc Serverless für Spark startet normalerweise eine Arbeitslast, die ein benutzerdefiniertes Container-Image erfordert indem Sie das gesamte Image auf die Festplatte herunterladen. Dies kann zu einer Verzögerung bei der Initialisierung führen. insbesondere für Kunden mit großen Bildern.

Sie können stattdessen auch das Image-Streaming verwenden. Dabei handelt es sich um eine Methode zum Abrufen von Bilddaten auf einer bei Bedarf anpassen. So kann die Arbeitslast gestartet werden, ohne auf den gesamten Bild herunterladen, was möglicherweise die Initialisierungszeit verbessert. Um das Bild zu aktivieren Streaming starten möchten, müssen Sie den Container File System API. Außerdem müssen Sie Ihre Container-Images in Artifact Registry und Artifact Registry speichern Das Repository muss sich in derselben Region wie die Dataproc-Arbeitslast oder in einer Multiregion, das der Region entspricht, in der Ihre Arbeitslast ausgeführt wird. Wenn Dataproc das Image oder das Image-Streaming nicht unterstützt nicht verfügbar ist, lädt unsere Streaming-Implementierung das gesamte Bild. Folgendes wird für das Bildstreaming nicht unterstützt:

In diesen Fällen ruft Dataproc das gesamte Image ab, bevor die Arbeitslast gestartet wird.

Spark

Fügen Sie Spark nicht in Ihr benutzerdefiniertes Container-Image ein. Zur Laufzeit: Dataproc Serverless für Spark stellt Spark-Binärdateien und -Konfigurationen vom Host im Container bereit: Binärdateien werden im Verzeichnis /usr/lib/spark und Konfigurationen im Verzeichnis /etc/spark/conf-Verzeichnis. Vorhandene Dateien in diesen Verzeichnissen werden überschrieben von Dataproc Serverless für Spark zur Laufzeit.

Java-Laufzeitumgebung

Fügen Sie nicht Ihre eigene Java-Laufzeitumgebung (JRE) in Ihr benutzerdefiniertes Container-Image ein. Während der Laufzeit stellt Dataproc Serverless for Spark OpenJDK vom Host in den Container. Wenn Sie eine JRE in Ihr benutzerdefiniertes Container-Image aufnehmen, wird sie ignoriert.

Java-Pakete

Sie können JAR-Dateien als Abhängigkeiten von Spark-Arbeitslasten in Ihr benutzerdefiniertes Container-Image einfügen und Legen Sie die Umgebungsvariable SPARK_EXTRA_CLASSPATH so fest, dass die JAR-Dateien eingeschlossen werden. Dataproc Serverless for Spark Fügen Sie den Wert der Umgebungsvariablen in den Klassenpfad der Spark-JVM-Prozesse ein. Empfehlung: JAR-Dateien im Verzeichnis /opt/spark/jars ablegen und SPARK_EXTRA_CLASSPATH festlegen an /opt/spark/jars/*.

Sie können die Arbeitslast-JAR-Datei in Ihr benutzerdefiniertes Container-Image aufnehmen und dann mit einem lokalen Pfad darauf verweisen beim Senden der Arbeitslast, z. B. file:///opt/spark/jars/my-spark-job.jar Ein Beispiel finden Sie unter Spark-Batcharbeitslast mit einem benutzerdefinierten Container-Image senden.

Python-Pakete

Standardmäßig stellt Dataproc Serverless für Spark-Bereitstellungen bereit Conda vom Gastgeber an im Container zur Laufzeit das Verzeichnis /opt/dataproc/conda. PYSPARK_PYTHON ist auf /opt/dataproc/conda/bin/python gesetzt. Das Basisverzeichnis, /opt/dataproc/conda/bin ist in PATH enthalten.

Sie können Ihre Python-Umgebung mit Paketen in einem anderen Verzeichnis einschließen in Ihrem benutzerdefinierten Container-Image, z. B. in /opt/conda, und legen Sie PYSPARK_PYTHON auf /opt/conda/bin/python setzen.

Ihr benutzerdefiniertes Container-Image kann andere Python-Module enthalten, die nicht Teil der Python-Umgebung sind, z. B. Python-Scripts mit Dienstprogrammfunktionen. Legen Sie die Umgebungsvariable PYTHONPATH so fest, dass die Verzeichnisse eingeschlossen werden, in denen wo sich die Module befinden.

R-Umgebung

Sie können die R-Umgebung in Ihrem benutzerdefinierten Container-Image mit einer der folgenden Optionen anpassen:

  • Verwenden Sie Conda, um R-Pakete aus dem Kanal conda-forge zu verwalten und zu installieren.
  • R-Repository für das Linux-Betriebssystem des Container-Images hinzufügen und R-Pakete installieren mit dem Linux OS-Paketmanager (siehe R-Software-Paketindex.

Wenn Sie eine der beiden Optionen verwenden, müssen Sie die Umgebungsvariable R_HOME festlegen. um auf Ihre benutzerdefinierte R-Umgebung zu verweisen. Ausnahme: Wenn Sie Conda für sowohl Ihre R-Umgebung zu verwalten als auch Ihre Python-Umgebung anzupassen, Sie müssen die Umgebungsvariable R_HOME nicht festlegen. wird es automatisch wird basierend auf der Umgebungsvariable PYSPARK_PYTHON festgelegt.

Beispiel für einen benutzerdefinierten Container-Image-Build

Dieser Abschnitt enthält ein Build-Beispiel für ein benutzerdefiniertes Container-Image, mit einem Beispiel-Dockerfile.

Dockerfile

# Debian 11 is recommended.
FROM debian:11-slim

# Suppress interactive prompts
ENV DEBIAN_FRONTEND=noninteractive

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

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

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

# (Optional) 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}"
COPY spark-bigquery-with-dependencies_2.12-0.22.2.jar "${SPARK_EXTRA_JARS_DIR}"

# (Optional) Install and configure Miniconda3.
ENV CONDA_HOME=/opt/miniconda3
ENV PYSPARK_PYTHON=${CONDA_HOME}/bin/python
ENV PATH=${CONDA_HOME}/bin:${PATH}
COPY Miniconda3-py39_4.10.3-Linux-x86_64.sh .
RUN bash Miniconda3-py39_4.10.3-Linux-x86_64.sh -b -p /opt/miniconda3 \
  && ${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 --prepend channels conda-forge \
  && ${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/conda install ipython ipykernel

# (Optional) Install Conda packages.
#
# The following packages are installed in the default image, it is strongly
# recommended to include all of them.
#
# Use mamba to install packages quickly.
RUN ${CONDA_HOME}/bin/conda install mamba -n base -c conda-forge \
    && ${CONDA_HOME}/bin/mamba install \
      conda \
      cython \
      fastavro \
      fastparquet \
      gcsfs \
      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 \
      koalas \
      matplotlib \
      nltk \
      numba \
      numpy \
      openblas \
      orc \
      pandas \
      pyarrow \
      pysal \
      pytables \
      python \
      regex \
      requests \
      rtree \
      scikit-image \
      scikit-learn \
      scipy \
      seaborn \
      sqlalchemy \
      sympy \
      virtualenv

# (Optional) Add extra Python modules.
ENV PYTHONPATH=/opt/python/packages
RUN mkdir -p "${PYTHONPATH}"
COPY test_util.py "${PYTHONPATH}"

# (Optional) Install R and R libraries.
RUN apt update \
  && apt install -y gnupg \
  && apt-key adv --no-tty \
      --keyserver "hkp://keyserver.ubuntu.com:80" \
      --recv-keys E19F5F87128899B192B1A2C2AD5F960A256A04AF \
  && echo "deb http://cloud.r-project.org/bin/linux/debian bullseye-cran40/" \
      >/etc/apt/sources.list.d/cran-r.list \
  && apt update \
  && apt install -y \
      libopenblas-base \
      libssl-dev \
      r-base \
      r-base-dev \
      r-recommended \
      r-cran-blob

ENV R_HOME=/usr/lib/R

# (Required) 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

Build-Befehle

Führen Sie die Datei im Dockerfile-Verzeichnis aus.

IMAGE=gcr.io/my-project/my-image:1.0.1

# Download the BigQuery connector.
gcloud storage cp \
  gs://spark-lib/bigquery/spark-bigquery-with-dependencies_2.12-0.22.2.jar .

# Download the Miniconda3 installer.
wget https://repo.anaconda.com/miniconda/Miniconda3-py39_4.10.3-Linux-x86_64.sh

# Python module example
cat >test_util.py <<EOF
def hello(name):
  print("hello {}".format(name))

def read_lines(path):
  with open(path) as f:
    return f.readlines()
EOF

# Build and push the image.
docker build -t "${IMAGE}" .
docker push "${IMAGE}"