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 batches 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
。- 其他批处理命令选项:您可以添加其他可选批处理的命令标志,例如,使用持久性历史记录服务器 (PHS)。注意: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
资源文档)。如需使用 Persistent History Server (PHS),请参阅设置 Persistent History Server。注意:PHS 必须位于您运行批处理工作负载的区域。
HTTP 方法和网址:
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 以 spark
Linux 用户身份通过 1099
UID 和 1099
GID 来运行容器。自定义容器映像 Dockerfile 中设置的 USER
指令在运行时被忽略。使用 UID 和 GID 获得文件系统权限。
例如,如果您将映像中位于 /opt/spark/jars/my-lib.jar
中的 jar 文件添加为工作负载依赖项,则必须向 spark
用户授予该文件的读取权限。
映像流式传输
Dataproc Serverless for Spark 通常会将整个映像下载到磁盘,以启动需要自定义容器映像的工作负载。这可能会导致初始化时间延迟,对于有大量图片的客户来说尤其如此。
您可以改用映像流式传输,这种方法可根据需要拉取映像数据。这样一来,工作负载便可以启动,而无需等待整个映像下载完毕,从而可能缩短初始化时间。如需启用映像流式传输,您必须启用 Container File System API。您还必须将容器映像存储在 Artifact Registry 中,并且 Artifact Registry 代码库必须与您的 Dataproc 工作负载位于同一区域,或者位于与工作负载运行区域相对应的多区域中。如果 Dataproc 不支持映像或映像流式传输服务不可用,我们的流式传输实现会下载整个映像。
请注意,我们不支持以下图片流式传输:
- 包含空层或重复层的图片
- 使用 V2 映像清单,架构版本 1 的映像
在这些情况下,Dataproc 会先拉取整个映像,然后再启动工作负载。
Spark
请勿在自定义容器映像中包含 Spark。在运行时,Dataproc Serverless for Spark 将 Spark 二进制文件和配置从主机装载到容器中:二进制文件装载到 /usr/lib/spark
目录,配置装载到 /etc/spark/conf
目录。Dataproc Serverless for Spark 在运行时会替换这些目录中的现有文件。
Java 运行时环境
请勿在您的自定义容器映像中添加自己的 Java 运行时环境 (JRE)。在运行时,Dataproc Serverless for Spark 将 OpenJDK
从主机装载到容器中。如果您在自定义容器映像中包含 JRE,则该映像将被忽略。
Java 软件包
您可以将 jar 文件作为 Spark 工作负载依赖项添加到自定义容器映像中,也可以设置 SPARK_EXTRA_CLASSPATH
环境变量以包含 jar。Dataproc Serverless for Spark 会将环境变量值添加到 Spark JVM 进程的类路径中。建议:将 jar 放入/opt/spark/jars
目录下并将 SPARK_EXTRA_CLASSPATH
设置为 /opt/spark/jars/*
。
您可以在自定义容器映像中添加工作负载 jar,然后在提交工作负载时通过本地路径引用该工作负载,例如 file:///opt/spark/jars/my-spark-job.jar
(如需查看示例,请参阅使用自定义容器映像提交 Spark 批处理工作负载)。
Python 软件包
默认情况下,Dataproc Serverless for Spark 会在运行时将 Conda 从主机装载到容器中的 /opt/dataproc/conda
目录中。PYSPARK_PYTHON
设置为 /opt/dataproc/conda/bin/python
。其基本目录 /opt/dataproc/conda/bin
包含在 PATH
中。
您可以将 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 软件包索引)。
使用任一选项时,您都必须将 R_HOME
环境变量设置为指向自定义 R 环境。例外情况:如果您同时使用 Conda 管理 R 环境和自定义 Python 环境,则无需设置 R_HOME
环境变量;系统会根据 PYSPARK_PYTHON
环境变量自动设置该变量。
自定义容器映像构建示例
本部分包含自定义容器映像构建示例,其中包括 Dockerfiles 示例,后跟构建命令。其中一个示例包含构建映像所需的最低配置。另一个示例包含额外配置的示例,包括 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。
# Build and push the image. gcloud builds submit --region=REGION \ --tag REGION-docker.pkg.dev/PROJECT/REPOSITORY/IMAGE_NAME:IMAGE_VERSION