Docker中提交任務到Spark叢集

MyStitch發表於2020-07-03

1.  背景描述和需求

資料分析程式部署在Docker中,有一些分析計算需要使用Spark計算,需要把任務提交到Spark叢集計算。

接收程式部署在Docker中,主機不在Hadoop叢集上。與Spark叢集網路互通。

 

需求如下

1、在Docker中可程式化向Spark叢集提交任務

2、在Docker中可對Spark任務管理,狀態查詢和結束

 

2.  解決方案

在Docker中搭建一套Spark、Hadoop環境。任務通過spark-submit --master yarn --deploy-mode cluster來提交到Spark on YARN叢集執行。

任務監控通過hadoop的restful介面來監控和管理。

 

2.1.  Yarn client 模式為行不通

任務釋出的docker例項,不在spark叢集中,屬於非叢集機器。只有spark yarn模式的入口,但是hdfs無法與hadoop叢集通訊。

為什麼不能hdfs不能通訊?

每個docker啟動時,一般不指定ip地址和機器名,不能再叢集中預先配置好ip地址和機器名。

並且在hadoop叢集中新增了一個動態的docker,但是並不參與任務執行,不利於環境的管理。

在docker中,你的環境配置(python路徑,hadoop路徑等)可能與hadoop叢集不一致,所以以client模式執行時,存在找不到配置的錯誤。

以cluster模式執行,只要保證把任務所需的檔案上傳到hadoop叢集即可正常執行任務,docker不與叢集通訊業可以正常執行任務。

 

Client模式為何不行?

Client模式是由RM分配一個AM,然後由executor反向driver註冊,dirver傳送task,在回收結果。

但是現在dirver在Docker中,executor找不到dirver的地址,無法註冊,所以導致client模式無法使用。

 

https://www.cnblogs.com/fbiswt/p/4667956.html

1、客戶端安裝的機器一般是虛擬機器,虛擬機器的名稱可能是隨便搞的,然而,yarn-client模式提交任務,是預設把本機當成driver的。所以導致其他的機器無法通過host的name直接訪問這臺機器。報錯就是Failed to connect to driver at x.x.x.x,retrying.....

 解決辦法:在命令後面加上一個--conf spark.driver.host=$your_ip_address,後面直接填客戶端機器的IP地址就行。還有一個辦法:export SPARK_JAVA_OPTS="-Dspark.driver.host=$your_ip_address",但是這種方法你在用完yarn-client後就沒有辦法再用yarn-cluster了。千萬不能把這個引數配置到spark-default.conf裡面。

 

2.2.  Cluster與client模式異同

Cluster模式,driver節點在叢集內部,可以最大限度的減少driver和executor直接的網路延時。

這部分內容有詳細介紹。

 

3.  Spark on Yarn叢集環境搭建

3.1.  Spark on Yarn叢集搭建

資源管理模式設定為YARN模式,開放Hadoop Web管理頁面。

 

詳細搭建過程略。網上有詳細文件。

 

3.2.  Web管理頁面和rest配置

hadoop目錄etc/Hadoop目錄yarn-site.xml檔案

通過yarn.resourcemanager.webapp.address 設定web訪問地址和埠

 

<!-- Site specific YARN configuration properties -->

 <property>

  <name>yarn.nodemanager.aux-services</name>

  <value>mapreduce_shuffle</value>

</property>

<property>

   <name>yarn.resourcemanager.address</name>

   <value>master:8032</value>

</property>

<property>

  <name>yarn.resourcemanager.scheduler.address</name>

  <value>master:8030</value>

</property>

<property>

 <name>yarn.resourcemanager.resource-tracker.address</name>

 <value>master:8031</value>

</property>

<property>

 <name>yarn.resourcemanager.admin.address</name>

 <value>master:8033</value>

</property>

<property>

 <name>yarn.resourcemanager.webapp.address</name>

 <value>IP address:8088</value>

</property>

 

4.  Docker環境搭建和設定

4.1.  軟體配套表

編號

軟體名稱

軟體版本

1

Java

java version "1.8.0_121"

Java(TM) SE Runtime Environment (build 1.8.0_121-b13)

Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

2

Spark

spark-2.3.2-bin-hadoop2.7

3

Hadoop

hadoop-2.7.3

4

Linux os

Centos 6.5 64bit

5

Docker

17.09.0-ce

6

Python

anaconda3:4.2.0

 

4.2.  製作Spark的Docker映象

 

安裝基礎軟體

把java、spark、hadoop、python的軟體放到同一個目錄下,在Dockerfile中使用ADD命令新增軟體到映象。

軟體放到了./add 目錄下,通過ADD命令把目錄下的軟體新增到Docker中的/目錄

   ADD ./add /

 

軟體環境變數設定

這裡以把java、spark、hadoop、anaconda3:4.2.0都放到根目錄下為例:

# Spark ENV

JAVA_HOME="/jdk1.8.0_121"

SPARK_HOME="/spark-2.3.2-bin-hadoop2.7"

HADOOP_HOME="/hadoop-2.7.3"

CLASSPATH="/anaconda3/bin;/jdk1.8.0_121/lib/dt.jar:/jdk1.8.0_121/lib/tools.jar"

PATH="/jdk1.8.0_121/bin:$PATH:/spark-2.3.2-bin-hadoop2.7/bin:/hadoop-2.7.3/bin"

 

Hadoop配置

Hadoop配置檔案直接使用spark叢集中的hadoop配置即可。路徑為hadoop_dir/etc/Hadoop,把目錄下的配置都複製過來即可。

 

提示:

如果Docker中java路徑與Spark中一致,則需要修改為docker中的路徑。不然docker中spark無法執行

 

如果提交的是任務是python程式,則PYSPARK_PYTHON設定要求與spark叢集的配置保持一致。

通過PYSPARK_PYTHON="/anaconda3/bin/python"來設定

 

在Docker的程式中,執行使用者與spark叢集中的執行賬戶可能不一致,則需要通過環境變數HADOOP_USER_NAME來設定。與叢集中保持一致,不然會產生許可權問題。

HADOOP_USER_NAME="spark"

 

Dockerfile示例

 

FROM your_base_env

ENV LANG="en_US.UTF-8"

 

ADD ./add .

 

# Spark ENV

ENV JAVA_HOME="/jdk1.8.0_121" SPARK_HOME="/spark-2.3.2-bin-hadoop2.7" HADOOP_HOME="/hadoop-2.7.3" CLASSPATH="/jdk1.8.0_121/lib/dt.jar:/jdk1.8.0_121/lib/tools.jar" \

PATH="/jdk1.8.0_121/bin:$PATH:/spark-2.3.2-bin-hadoop2.7/bin:/hadoop-2.7.3/bin" PATH="$PATH:$INSTALL_PATH" PYTHONPATH="$INSTALL_PATH" LANG="en_US.UTF-8" \

HADOOP_CONF_DIR="/hadoop-2.7.3/etc/hadoop/ " PYSPARK_PYTHON="/anaconda3/bin/python" HADOOP_USER_NAME="spark"

 

 

4.3.  環境檢查

配置完成後,打包映象,啟動一個例項

檢查spark配置

輸入命令:spark-submit,檢查spark是否安裝完成

看到下面的資訊,說明spark設定成功

[root@3920e4505b70 stg]# spark-submit

Usage: spark-submit [options] <app jar | python file | R file> [app arguments]

Usage: spark-submit --kill [submission ID] --master [spark://...]

Usage: spark-submit --status [submission ID] --master [spark://...]

Usage: spark-submit run-example [options] example-class [example args]

 

Options:

  --master MASTER_URL         spark://host:port, mesos://host:port, yarn,

                              k8s://https://host:port, or local (Default: local[*]).

  --deploy-mode DEPLOY_MODE   Whether to launch the driver program locally ("client") or

                              on one of the worker machines inside the cluster ("cluster")

                              (Default: client).

  --class CLASS_NAME          Your application's main class (for Java / Scala apps).

  --name NAME                 A name of your application.

  --jars JARS                 Comma-separated list of jars to include on the driver

                              and executor classpaths.

  --packages                  Comma-separated list of maven coordinates of jars to include

                              on the driver and executor classpaths. Will search the local

                              maven repo, then maven central and any additional remote

                              repositories given by --repositories. The format for the

                              coordinates should be groupId:artifactId:version.

  --exclude-packages          Comma-separated list of groupId:artifactId, to exclude while

                              resolving the dependencies provided in --packages to avoid

                              dependency conflicts.

 

檢查Hadoop配置

輸入命令:yarn application -list 檢查hadoop叢集配置

看到下面輸出表示正常

[root@3920e4505b70 /]# yarn application -list

Total number of applications (application-types: [] and states: [SUBMITTED, ACCEPTED, RUNNING]):0

                Application-Id      Application-Name        Application-Type          User           Queue                   State             Final-State             Progress                        Tracking-URL

執行任務Demo

環境檢查沒有問題,執行demo程式碼來檢查下:

spark-submit --master yarn --deploy-mode cluster /spark-2.3.2-bin-hadoop2.7/examples/src/main/python/pi.py

沒有問題,則會看到任務狀態為ACCEPTED說明叢集接受了任務

RUNNING說明spark叢集開始執行任務了。

  

5.  任務監控

任務監控的兩個方法

  • Yarn 命令列
  • Hadoop HTTP rest介面

由於開發語言為python,呼叫shell命令沒有rest介面方便,選擇使用rest介面來做任務監控方案。

5.1.  yarn application命令監控和管理

通過命令檢視當前執行的任務,檢視自己執行的任務是否在列表中

 

yarn application –list 檢視任務列表

 

yarn application –kill  applicationID  結束指定任務

 

5.2.  hadoop叢集的rest介面來管理

在python中呼叫shell命令,存在諸多不便。

呼叫rest介面非常方便。這裡選擇rest介面作為任務狀態管理方式。

 

介面文件地:

https://hadoop.apache.org/docs/r2.7.3/hadoop-yarn/hadoop-yarn-site/ResourceManagerRest.html#Cluster_Application_API

 

5.2.1.  查詢任務列表

GET http://<rm http address:port>/ws/v1/cluster/apps

引數:states=accepted,running,finished

查詢條件過濾accepted,running,檢查提交的任務是否在任務列表中。

5.2.2.  查詢單個任務

如果任務已經接受了,生成了任務id,則可以直接根據任務id來查詢任務狀態

GET http://<rm http address:port>/ws/v1/cluster/apps/ application_1546828007170_0142

查詢剛才任務執行的結果:

{
    "app":{
        "id":"application_1546828007170_0142",
        "user":"csmsopr",
        "name":"pi.py",
        "queue":"default",
        "state":"FINISHED",
        "finalStatus":"SUCCEEDED",
        "progress":100,
        "trackingUI":"History",
        "trackingUrl":"http://host281566:8088/proxy/application_1546828007170_0142/",
        "diagnostics":"",
        "clusterId":1546828007170,
        "applicationType":"SPARK",
        "applicationTags":"",
        "startedTime":1548234101173,
        "finishedTime":1548234115661,
        "elapsedTime":14488,
        "amContainerLogs":"http://host281567:8042/node/containerlogs/container_1546828007170_0142_01_000001/csmsopr",
        "amHostHttpAddress":"host281567:8042",
        "allocatedMB":-1,
        "allocatedVCores":-1,
        "runningContainers":-1,
        "memorySeconds":51782,
        "vcoreSeconds":32,
        "preemptedResourceMB":0,
        "preemptedResourceVCores":0,
        "numNonAMContainerPreempted":0,
        "numAMContainerPreempted":0
    }
}

 

 

5.2.3.  任務狀態管理

任務狀態查詢和結束

PUT http://<rm http address:port>/ws/v1/cluster/apps/ application_1546828007170_0142/state

返回

{

  "state":"KILLED"

}

 

查詢任務狀態

GET http://<rm http address:port>/ws/v1/cluster/apps/ application_1546828007170_0142/state

返回:

{

  "state":"ACCEPTED"

}

 

6.  參考資料

Spark中yarn模式兩種提交任務方式

https://www.cnblogs.com/LHWorldBlog/p/8414342.html

 

Hadoop介面文件

 

https://hadoop.apache.org/docs/r2.7.3/hadoop-yarn/hadoop-yarn-site/ResourceManagerRest.html#Cluster_Application_API

 

相關文章