在 Amazon EMR 6.x 上使用 Docker 來執行 Spark 應用程式 - Amazon EMR

在 Amazon EMR 6.x 上使用 Docker 來執行 Spark 應用程式

透過 Amazon EMR 6.0.0,Spark 應用程式可以使用 Docker 容器來定義它們的程式庫相依性,而不用在叢集中的個別 Amazon EC2 執行個體上安裝相依項。要執行 Spark 與 Docker,您必須先設定 Docker 登錄檔並在提交 Spark 應用程式時定義其他參數。如需詳細資訊,請參閱設定 Docker 整合

在提交應用程式時,YARN 會叫用 Docker 以提取指定的 Docker 影像,並執行一個 Docker 容器內的 Spark 應用程式。這可讓您輕鬆定義並隔離依存項目。它可以使用作業執行所需的程式庫來減少引導或準備 Amazon EMR 叢集中執行個體的時間。

使用 Docker 執行 Spark 時的考量事項

使用 Docker 執行 Spark 時,請確保符合以下先決條件:

  • docker 套件和 CLI 只安裝在核心和任務節點上。

  • 在 Amazon EMR 6.1.0 及更高版本上,您也可以使用下列命令在主節點上安裝 Docker。

    • sudo yum install -y docker sudo systemctl start docker
  • spark-submit 命令應始終從 Amazon EMR 叢集的主執行個體上執行。

  • 用於解析 Docker 影像的 Docker 登錄檔必須使用具有 container-executor 分類索引鍵的分類 API 來定義,以便在啟動叢集時定義其他參數:

    • docker.trusted.registries

    • docker.privileged-containers.registries

  • 若要在 Docker 容器中執行 Spark 應用程式,以下為必要設定選項:

    • YARN_CONTAINER_RUNTIME_TYPE=docker

    • YARN_CONTAINER_RUNTIME_DOCKER_IMAGE={DOCKER_IMAGE_NAME}

  • 使用 Amazon ECR 擷取 Docker 映像檔時,您必須設定叢集以讓其自行驗證。若要執行此操作,您必須使用下列組態選項:

    • YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG={DOCKER_CLIENT_CONFIG_PATH_ON_HDFS}

  • 在 EMR 6.1.0 及更高版本中,您不需要在啟用 ECR 自動身分驗證功能時使用列出的命令 YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG={DOCKER_CLIENT_CONFIG_PATH_ON_HDFS}

  • 任何與 Spark 一起使用的 Docker 影像,都必須在該 Docker 影像中安裝 Java。

如需有關先決條件的詳細資訊,請參閱設定 Docker 整合

建立 Docker 映像檔

Docker 影像是使用 Dockerfile 建立的,該檔案會定義要包含在映像中的套件和組態。以下兩個範例 Dockerfile 使用 PySpark 和 SparkR。

PySpark Dockerfile

從此 Dockerfile 建立的 Docker 影像包括 Python 3 和 NumPy Python 套件。該 Dockerfile 使用 Amazon Linux 2 和 Amazon Corretto JDK 8。

FROM amazoncorretto:8 RUN yum -y update RUN yum -y install yum-utils RUN yum -y groupinstall development RUN yum list python3* RUN yum -y install python3 python3-dev python3-pip python3-virtualenv RUN python -V RUN python3 -V ENV PYSPARK_DRIVER_PYTHON python3 ENV PYSPARK_PYTHON python3 RUN pip3 install --upgrade pip RUN pip3 install numpy pandas RUN python3 -c "import numpy as np"

SparkR Dockerfile

從此 Dockerfile 建立的 Docker 影像包括 R 和 randomForest CRAN 套件。這個 Dockerfile 包括 Amazon Linux 2 和 Amazon Corretto JDK 8。

FROM amazoncorretto:8 RUN java -version RUN yum -y update RUN amazon-linux-extras install R4 RUN yum -y install curl hostname #setup R configs RUN echo "r <- getOption('repos'); r['CRAN'] <- 'http://cran.us.r-project.org'; options(repos = r);" > ~/.Rprofile RUN Rscript -e "install.packages('randomForest')"

如需有關 Dockerfile 語法的更多資訊,請參閱 Dockerfile 參考文件

使用 Amazon ECR 的 Docker 映像檔

Amazon Elastic Container Registry (Amazon ECR) 是一種完全受管的 Docker 容器登錄檔,可讓您輕鬆存放、管理和部署 Docker 容器映像。使用 Amazon ECR 時,叢集必須設定為信任您的 ECR 執行個體,而且您必須設定身分驗證,才能讓叢集使用來自 Amazon ECR 的 Docker 映像檔。如需詳細資訊,請參閱設定 YARN 以存取 Amazon ECR

若要確定 EMR 主機可以存取存放在 Amazon ECR 中的映像,您叢集擁有的許可必須來自與執行個體設定檔相關聯的 AmazonEC2ContainerRegistryReadOnly 政策。如需詳細資訊,請參閱 AmazonEC2ContainerRegistryReadOnly 政策

在此範例中,叢集必須使用下列其他組態來建立,以確保 Amazon ECR 登錄檔受到信任。使用您的 Amazon ECR 端點取代 123456789123.dkr.ecr.us-east-1.amazonaws.com 端點。

[ { "Classification": "container-executor", "Configurations": [ { "Classification": "docker", "Properties": { "docker.privileged-containers.registries": "local,centos,123456789123.dkr.ecr.us-east-1.amazonaws.com", "docker.trusted.registries": "local,centos,123456789123.dkr.ecr.us-east-1.amazonaws.com" } } ], "Properties": {} } ]

搭配使用 PySpark 和 Amazon ECR

以下範例使用 PySpark Dockerfile,並將被標記並上傳到 Amazon EC。Dockerfile 上傳後,您可以執行 PySpark 作業並從 Amazon ECR 中參閱 Docker 映像檔。

啟動叢集後,使用 SSH 連接到核心節點,並執行以下命令以從 PySpark Dockerfile 範例建構本機 Docker 影像。

首先,建立一個目錄和一個 Dockerfile。

mkdir pyspark vi pyspark/Dockerfile

貼上 PySpark Dockerfile 的內容,並執行以下命令來建構一個 Docker 影像。

sudo docker build -t local/pyspark-example pyspark/

為範例建立 emr-docker-examples ECR 儲存庫。

aws ecr create-repository --repository-name emr-docker-examples

標記在本機建構的映像並上傳至 ECR,並以您的 ECR 端點取代 123456789123.dkr.ecr.us-east-1.amazonaws.com

sudo docker tag local/pyspark-example 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example sudo docker push 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example

使用 SSH 連線到主節點,並準備具有 main.py 檔名的 Python 指令碼。將下列內容貼入 main.py 檔案並儲存。

from pyspark.sql import SparkSession spark = SparkSession.builder.appName("docker-numpy").getOrCreate() sc = spark.sparkContext import numpy as np a = np.arange(15).reshape(3, 5) print(a)

在 EMR 6.0.0 上,若要提交作業,請參考 Docker 映像檔的名稱。定義其他組態參數,以確定任務執行使用 Docker 做為執行時間。使用 Amazon ECR 時,YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG 必須參考 config.json 檔案,該檔案包含用於向 Amazon ECR 進行驗證的登入資料。

DOCKER_IMAGE_NAME=123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example DOCKER_CLIENT_CONFIG=hdfs:///user/hadoop/config.json spark-submit --master yarn \ --deploy-mode cluster \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG=$DOCKER_CLIENT_CONFIG \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG=$DOCKER_CLIENT_CONFIG \ --num-executors 2 \ main.py -v

在 EMR 6.1.0 及更高版本上,若要提交作業,請參考 Docker 映像檔的名稱。啟用 ECR 自動身分驗證時,請執行以下命令。

DOCKER_IMAGE_NAME=123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example spark-submit --master yarn \ --deploy-mode cluster \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \ --num-executors 2 \ main.py -v

當任務完成時,請記下 YARN 應用程式 ID,並使用下列命令來取得 PySpark 任務的輸出。

yarn logs --applicationId application_id | grep -C2 '\[\[' LogLength:55 LogContents: [[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14]]

搭配使用 SparkR 和 Amazon ECR

下面的範例使用將被標記並上傳到 ECR 的 SparkR Dockerfile。一旦 Dockerfile 上傳後,您便可以執行 SparkR 作業並從 Amazon ECR 中參考 Docker 映像檔。

啟動叢集後,使用 SSH 連接到核心節點,並執行以下命令以從 SparkR Dockerfile 範例建構本機 Docker 影像。

首先,建立一個目錄和 Dockerfile。

mkdir sparkr vi sparkr/Dockerfile

貼上 SparkR Dockerfile 的內容,並執行以下命令來建構一個 Docker 影像。

sudo docker build -t local/sparkr-example sparkr/

標記在本機建構的映像並上傳至 Amazon ECR,並使用您的 Amazon ECR 端點取代 123456789123.dkr.ecr.us-east-1.amazonaws.com

sudo docker tag local/sparkr-example 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example sudo docker push 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example

使用 SSH 連接到主節點,並準備具有 sparkR.R 名稱的 R 指令碼。將以下內容貼到 sparkR.R 檔案。

library(SparkR) sparkR.session(appName = "R with Spark example", sparkConfig = list(spark.some.config.option = "some-value")) sqlContext <- sparkRSQL.init(spark.sparkContext) library(randomForest) # check release notes of randomForest rfNews() sparkR.session.stop()

在 EMR 6.0.0 上,若要提交作業,請參考 Docker 映像檔的名稱。定義其他組態參數,以確定任務執行使用 Docker 做為執行時間。使用 Amazon ECR 時,YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG 必須參考 config.json 檔案,該檔案包含用於向 ECR 進行驗證的登入資料。

DOCKER_IMAGE_NAME=123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example DOCKER_CLIENT_CONFIG=hdfs:///user/hadoop/config.json spark-submit --master yarn \ --deploy-mode cluster \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG=$DOCKER_CLIENT_CONFIG \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG=$DOCKER_CLIENT_CONFIG \ sparkR.R

在 EMR 6.1.0 及更高版本上,若要提交作業,請參考 Docker 映像檔的名稱。啟用 ECR 自動身分驗證時,請執行以下命令。

DOCKER_IMAGE_NAME=123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example spark-submit --master yarn \ --deploy-mode cluster \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \ sparkR.R

當任務完成後,請記下 YARN 應用程式 ID,並使用下面的命令來取得 SparkR 任務的輸出。此範例包含測試,以確定 randomForest 程式庫、安裝的版本和版本備註都可以使用。

yarn logs --applicationId application_id | grep -B4 -A10 "Type rfNews" randomForest 4.6-14 Type rfNews() to see new features/changes/bug fixes. Wishlist (formerly TODO): * Implement the new scheme of handling classwt in classification. * Use more compact storage of proximity matrix. * Allow case weights by using the weights in sampling? ======================================================================== Changes in 4.6-14: