1. 背景描述和需求html
數據分析程序部署在Docker中,有一些分析計算須要使用Spark計算,須要把任務提交到Spark集羣計算。java
接收程序部署在Docker中,主機不在Hadoop集羣上。與Spark集羣網絡互通。node
需求以下python
一、在Docker中可程序化向Spark集羣提交任務web
二、在Docker中可對Spark任務管理,狀態查詢和結束docker
在Docker中搭建一套Spark、Hadoop環境。任務經過spark-submit --master yarn --deploy-mode cluster來提交到Spark on YARN集羣執行。shell
任務監控經過hadoop的restful接口來監控和管理。apache
任務發佈的docker實例,不在spark集羣中,屬於非集羣機器。只有spark yarn模式的入口,可是hdfs沒法與hadoop集羣通訊。restful
爲何不能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
一、客戶端安裝的機器通常是虛擬機,虛擬機的名稱多是隨便搞的,然而,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裏面。
Cluster模式,driver節點在集羣內部,能夠最大限度的減小driver和executor直接的網絡延時。
這部份內容有詳細介紹。
資源管理模式設置爲YARN模式,開放Hadoop Web管理頁面。
詳細搭建過程略。網上有詳細文檔。
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>
編號 |
軟件名稱 |
軟件版本 |
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 |
把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配置文件直接使用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"
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"
配置完成後,打包鏡像,啓動一個實例
輸入命令: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.
輸入命令: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代碼來檢查下:
spark-submit --master yarn --deploy-mode cluster /spark-2.3.2-bin-hadoop2.7/examples/src/main/python/pi.py
沒有問題,則會看到任務狀態爲ACCEPTED說明集羣接受了任務
RUNNING說明spark集羣開始執行任務了。
任務監控的兩個方法
因爲開發語言爲python,調用shell命令沒有rest接口方便,選擇使用rest接口來作任務監控方案。
經過命令查看當前運行的任務,查看本身運行的任務是否在列表中
yarn application –list 查看任務列表
yarn application –kill applicationID 結束指定任務
在python中調用shell命令,存在諸多不便。
調用rest接口很是方便。這裏選擇rest接口做爲任務狀態管理方式。
接口文檔地:
GET http://<rm http address:port>/ws/v1/cluster/apps
參數:states=accepted,running,finished
查詢條件過濾accepted,running,檢查提交的任務是否在任務列表中。
若是任務已經接受了,生成了任務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 } }
任務狀態查詢和結束
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"
}
Spark中yarn模式兩種提交任務方式 |
https://www.cnblogs.com/LHWorldBlog/p/8414342.html
|
Hadoop接口文檔
|