0 前言
大家好,我是小林!
本篇文章是 Spark 系列的第三篇文章,

在第二篇文章中,小林講到一個 Spark 任務首先要生成資料依賴圖,也就是 Job 的邏輯執行圖,然后根據一定的規則轉化成 Job 的物理執行圖,才能真正的執行,并且在第一篇文章中舉了一個 word count 的例子,你可以回顧下這兩張圖,理解一下第二篇講的邏輯執行圖到物理執行圖的轉換:


上面第一張圖描述的是資料依賴關系,是一種抽象的流程圖,而第二張圖是實際可以執行的一個個任務流圖,每條 task 流水線都會有資料集抽象,供于計算,所以,前者是一個總覽的流程圖,后者是一個實實在在可以執行的任務流程圖,他們之間的聯系就是,Job 物理執行圖會根據邏輯執行轉換成物理執行,
你可能會很好奇,小林為什么一直在提 Job 物理執行圖會根據邏輯執行轉換成實際的物理執行?原因是分布式的精髓,在于如何把抽象的計算流圖,轉化為實實在在的分布式計算任務,然后以并行計算的方式交付執行,
本文,小林跟大家聊聊,Spark 內部有哪些行程,它們是如何協作實作分布式計算?
在企業里有哪些 Spark 部署方式?
Spark 任務的提交方式有哪些?
1 Spark 有哪些行程?
小林先給出一張總體的部署圖,來熟悉下,Spark 系統中有哪些角色和行程,

從上述架構圖中可以看到 :
-
整個 Spark 集群中分為 Master 節點和 Worker 節點,相當于 Hadoop 的 Master 和 Slave 節點,
-
Master 節點上常駐 Master 守護行程,負責管理全部的 Worker 節點,
-
Worker 節點上常駐 Worker 守護行程,負責與 Master 節點通信并管理 executors,
-
Driver 官方解釋是 “The process running the main function of the application and creating the SparkContext”,SparkContext 包羅萬象,它在提供 Spark 運行時背景關系的同時(包括調度系統,存盤系統,記憶體管理,RPC 通信),也可以為為我們提供創建、轉換、計算分布式資料集的開發 API,
Application 就是用戶自己寫的 Spark 程式(driver program),比如 WordCount.scala,如果 driver program 在 Master 上運行,比如在 Master 上 執行以下命令:
./bin/run SparkPi 10
那么 SparkPi 就是 Master 上的 Driver,如果是 YARN 集群,那么 Driver 可能被調度到 Worker 節點上運行,
-
每個 Worker 上存在一個或者多個 ExecutorBackend 行程,每個行程包含一個 Executor 物件,該物件 持有一個執行緒池,每個執行緒可以執行一個 task,
-
每個 application 包含一個 driver 和多個 executors,每個 executor 里面運行的 tasks 都屬于 同一個 application, 在 Standalone 版本中,ExecutorBackend 被實體化成 CoarseGrainedExecutorBackend 行程,
-
Worker 通過持有 ExecutorRunner 物件來控制 CoarseGrainedExecutorBackend 的啟停,
總結一下就是,在 Spark 集群中,一共有 4 種行程,Master 和 Worker 行程,屬于資源調度行程,Master 負責整個集群中的資源監控及調度,Worker 負責某臺節點的資源調度,它會通過與 Master 通信匯報當臺節點的資源使用情況;Driver 和 Executor 行程,是任務調度行程,Driver 主要作用是決議用戶代碼,構建資料依賴圖,然后將資料依賴圖轉換為分布式任務,并把任務分發到集群中的 Executor 執行,Executor 則是屬于真正執行任務的行程,并且會把任務進展向 Driver 進行匯報,
2 Spark 分布式環境部署
Spark 支持很多種分布式部署模式,其中包括,Standalone、YARN、Mesos 以及 Kubernetes,Standalone 是 Spark 自帶的資源調度框架,YARN、Mesos以及 Kubernetes 是獨立的第三方資源調度框架,本文根據生產中使用較多的兩種場景,講解 Standalone 集群搭建和 Spark on YARN 配置,
Standalone 集群搭建
Standalone 在資源調度層面,采取的是一主多從的架構,Master 在集群中有且僅有一個,worker 可以有多個,所有的 Worker 節點周期性的向 Master 匯報當前節點資源狀態,Master 負責統籌整個集群的資源,并對于 Driver 的資源請求做出回應,
對于學習的話,小林建議搭建 3 臺 Standalone 集群,1 臺 Master節點,2 臺 worker 節點,我在 VMware 準備了 4 臺虛擬機,為了講解后續不同的任務提交方式,特意多準備了一臺客戶端節點,節點規劃如下:

第一步,為了保證集群中各個節點間的免密鑰通信,在 4 臺節點間配置免密鑰通信環境;
#1.在每臺節點上,使用非對稱加密演算法,生成各自的私鑰、公鑰對
ssh-keygen -t rsa
#2.讀取各個節點間公鑰內容
cat /home/centos/.ssh/id_rsa.pub
#3.將每個節點的公鑰內容,追加到其它 3 臺節點
vim ~/.ssh/authorized
第二步,在安裝 Spark 前,需要先安裝 Java ,并配置 JAVA_HOME;
#安裝配置 Java 環境,將官網下載好的 Java 安裝包,上傳到虛擬機
vi /etc/profile
#配置JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_181
#重新生效 profile 檔案
source /etc/profile

第三步,我們安裝 Spark,先在官網上:spark.apache.org 下載安裝包,小林下載的是 spark-2.3.1-bin-hadoop2.6.tgz 壓縮包,將下載好的壓縮包上傳到 Master 節點,在 Master 節點上按照如下步驟操作:
#1.解壓上傳的安裝包
tar -zxvf ./spark-2.3.1-bin-hadoop2.6.tgz
#2.進入到安裝包的 conf 目錄下,配置 slaves.template 中的 worker 節點
mv slaves.template slaves
vi slaves
輸入以下內容:

#3.配置 spark-env.sh.template 檔案
mv spark-env.sh.template spark-env.sh
#4.配置如下內容:
export SPARK_MASTER_HOST=node1 #master的 ip
export SPARK_MASTER_PORT=7077 #提交任務的埠,默認是7077
export SPARK_WORKER_MEMORY=3g #每個 worker 能夠支配的記憶體數
export SPARK_WORKER_CORES=2 #每個worker 從節點能夠支配的 core 的個數
export JAVA_HOME=/opt/module/jdk1.8.0_181 #依賴的 Java 環境
#5.同步該安裝包到其它節點上,node2 和 node3
scp -r ./spark-2.3.1-bin-hadoop2.6 node2:`pwd`
scp -r ./spark-2.3.1-bin-hadoop2.6 node3:`pwd`
#6.啟動集群,進入 sbin 目錄下,執行命令
./start-all.sh
至此, Spark 集群,Standalone 模式已經搭建完畢!細心的小伙伴可能已經發現,不是還有 client 要搭建嘛,怎么步驟中沒有看到?搭建客戶端很簡單,只需要將下載的 Spark 安裝包,原封不動的上傳到 node04 節點即可,
Spark on YANR 配置
在講 Spark on YARN 的前提是,小林已經把 Hadoop 集群給配置好了,由于 Hadoop 集群配置不是本文的重點,本文不講 YARN 的配置,默認 YARN 已經配置好了,Spark 基于 YARN 進行任務調度,只需要在 Spark 客戶端(node04)做如下配置即可:

至此,Spark 分布式環境已經部署完,我們可以使用 Spark pi 任務測驗,standalone 環境部署是否成功,
standalone 提交命令:
./spark-submit --master spark://node1:7077 --class
org.apache.spark.examples.SparkPi /opt/module/spark-2.3.1-bin-hadoop2.6/examples/jars/spark-examples_2.11-2.3.1.jar 100
Spark on YARN 提交命令:
./spark-submit --master yarn --class
org.apache.spark.examples.SparkPi ../examples/jars/spark- examples_2.11-2.3.1.jar 100
如果出現 pi 的計算結果為 3.14,說明分布式集群已經部署成功,
3 Spark 任務提交方式有哪些?
基于 Standalone 模式一共有 2 種提交任務的方式,分別是 cluster 提交和 client 提交,下面分別敘述兩種任務的提交方式,
standalone-client 提交任務方式
./spark-submit --master spark://mynode1:7077
--deploy-mode client
--class org.apache.spark.examples.SparkPi ../examples/jars/spark-examples_2.11- 2.3.1.jar 100
其執行流程如圖所示:

standalone-cluster 提交任務方式
./spark-submit --master spark://mynode1:7077
--deploy-mode cluster
--class org.apache.spark.examples.SparkPi ../examples/jars/spark-examples_2.11- 2.3.1.jar 100
為了方便理解,我也畫了 集群模式提交任務的流程:

對比下 client 和 cluster 兩種提交任務的方式,發現 Driver 行程所啟動的位置不一樣,對于 standalone-client 提交任務方式,Driver 行程會在客戶端啟動,這里的客 戶端就是指提交應用程式的當前節點,在 Driver 端可以看到 task 執行的情 況,
生產環境下建議不要使用 client 模式,是因為:假設要提交 100 個 Application 到集群運行,Driver 每次都會在 client 端啟動,那么就會導致 客戶端 100 次網卡流量暴增的問題,client 模式適用于程式測驗,不適用于生產環境,在客戶端可以看到 task 的執行和
對于 standalone-cluster 提交任務方式,Driver 行程是在集群某一臺 Worker 上啟動的,在客戶端是無法查看 task 的執行情況的,假設要提交 100 個 Application 到集群運行,每次 Driver 會 隨機在集群中某一臺 Worker 上啟動,那么這 100 次網卡流量暴增的問題 就散布在集群上,
所以,生產環境中,建議使用 cluster 模式提交任務,
4 總結
本文提到,分布式計算的核心在于,如何把抽象的邏輯執行圖(資料依賴圖),轉化為實實在在的分布式計算任務,之后并行計算,聊到了 Spark 的行程,Master 和 Worker 行程,屬于資源調度行程,Driver 和 Executor 屬于任務調度行程,Driver 和 Executors 進行協作,完成一個 Spark 應用程式的執行,
其中 Driver 主要決議用戶代碼,構建資料依賴圖,然后將資料依賴圖轉換為分布式任務,并通過 RPC 發給集群中的 Executors 執行,Executor 在收到任務后,會呼叫內部執行緒池,結合之前分配好的資料分片,并發執行任務代碼,
Executor 會負責處理 RDD 的一個資料分片子集,并且 Executor 在執行程序中,會向 Driver 匯報任務狀態,Driver 在收到任務狀態后,會依據 Job 的物理執行圖上劃分的 Stage,依次有序的將下一階段任務再次發給集群中的 Executor 執行,直到 Application 中所有的任務完成,
最后,我們介紹了 Spark 的 Standalone 模式的分布式環境搭建,并給出了詳細具體的實操步驟,闡述了客戶端和集群 2 中提交任務方式的區別,你重點要掌握分布式集群環境的搭建程序,
好了,這期的文章就到這里,我們下期再見!歡迎,點贊,在看分享!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/421695.html
標籤:其他
上一篇:訊息佇列可靠性和順序性消費
