上一篇說到Spark的yarn client運行模式,它與yarn cluster模式的主要區別就是前者Driver是運行在客戶端,后者Driver是運行在yarn集群中,yarn client模式一般用在互動式場景中,比如spark shell, spark sql等程式,但是該模式下運行在客戶端的Driver與Yarn集群有大量的網路互動,如果客戶端與集群之間的網路不是很好,可能會導致性能問題,因此一般在生產環境中,大部分還是采用yarn cluster模式運行spark程式,
下面具體還是用計算PI的程式來說明,examples中該程式有三個版本,分別采用Scala、Python和Java語言撰寫,本次用Python程式pi.py做說明,
1 from __future__ import print_function 2 3 import sys 4 from random import random 5 from operator import add 6 7 from pyspark.sql import SparkSession 8 9 10 if __name__ == "__main__": 11 """ 12 Usage: pi [partitions] 13 """ 14 spark = SparkSession\ 15 .builder\ 16 .appName("PythonPi")\ 17 .getOrCreate() 18 19 partitions = int(sys.argv[1]) if len(sys.argv) > 1 else 2 20 n = 100000 * partitions 21 22 def f(_): 23 x = random() * 2 - 1 24 y = random() * 2 - 1 25 return 1 if x ** 2 + y ** 2 <= 1 else 0 26 27 count = spark.sparkContext.parallelize(range(1, n + 1), partitions).map(f).reduce(add) 28 print("Pi is roughly %f" % (4.0 * count / n)) 29 30 spark.stop()
程式邏輯與上一篇Scala程式一樣,就不再多做說明了,
下面來以yarn cluster方式來執行這個程式,注意執行程式前先要啟動hdfs和yarn,最好同時啟動spark的history server,這樣即使在程式運行完以后也可以從Web UI中查看到程式運行情況,
輸入以下命令:
[root@BruceCentOS4 ~]# $SPARK_HOME/bin/spark-submit --master yarn --deploy-mode cluster $SPARK_HOME/examples/src/main/python/pi.py
以下是程式運行輸出資訊部分截圖,
開始部分:

中間部分:

結束部分:

由于程式是以yarn cluster方式運行的,因此Driver是運行在Yarn集群當中(在BruceCentOS3上的ApplicationMaster行程當中),同時在BruceCentOS和BruceCentOS2上各運行了1個Executor行程(行程名字:CoarseGrainedExecutorBackend),而BruceCentOS4上的SparkSubmit行程僅僅作為yarn client向yarn集群提交spark程式,作為對比,在yarn client模式當中,客戶端SparkSubmit行程不僅作為yarn client提交程式,而且同時還會運行Driver,并啟動SparkContext,并且向Executor分配和管理Task,最后收集運行結果,因此yarn client模式程式輸出資訊會顯示最終的列印結果,然而在yarn cluster模式當中,由于Driver運行在yarn集群的ApplicationMaster中,因此最終結果需要到ApplicationMaster行程的日志中取查看,可以通過如下命令查看,

SparkUI上的Executor資訊:

BruceCentOS4上的客戶端行程:

BruceCentOS3上的ApplicationMaster行程(包含Spark Driver):

BruceCentOS上的Executor:

BruceCentOS2上的Executor:

下面具體描述下Spark程式在yarn cluster模式下運行的具體流程,
這里是一個流程圖:

- Spark Yarn Client向YARN提交應用程式,類似于MapReduce向Yarn提交程式,會將程式檔案、庫檔案和組態檔等上傳到HDFS,
- ResourceManager收到請求后,在集群中選擇一個NodeManager,為該應用程式分配第一個Container,要求它在這個Container中啟動應用程式的ApplicationMaster,其中ApplicationMaster中會運行Spark Driver,并進行SparkContext的初始化,
- ApplicationMaster向ResourceManager注冊,這樣用戶可以直接通過ResourceManager查看應用程式的運行狀態,然后它將采用輪詢的方式通過RPC協議為各個任務申請資源,并監控它們的運行狀態直到運行結束,
- 一旦ApplicationMaster申請到資源(也就是Container)后,便與對應的NodeManager通信,要求它在獲得的Container中啟動CoarseGrainedExecutorBackend,CoarseGrainedExecutorBackend啟動后會向ApplicationMaster中的SparkContext注冊并申請Task,這一點和Standalone模式一樣,只不過SparkContext在Spark Application中初始化時,使用CoarseGrainedSchedulerBackend配合YarnClusterScheduler進行任務的調度,
- ApplicationMaster中的SparkContext分配Task給CoarseGrainedExecutorBackend執行,CoarseGrainedExecutorBackend運行Task并向ApplicationMaster匯報運行的狀態和進度,以讓ApplicationMaster隨時掌握各個任務的運行狀態,從而可以在任務失敗時重新啟動任務,
- 應用程式運行完成后,ApplicationMaster向ResourceManager申請注銷并關閉自己,
以上就是個人對Spark運行模式(yarn cluster)的一點理解,其中參考了“求知若渴 虛心若愚”博主的“Spark(一): 基本架構及原理”的部分內容(其中基于Spark2.3.0對某些細節進行了修正),在此表示感謝,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/44424.html
標籤:大數據
上一篇:elasticsearch入門
下一篇:頻繁項集的產生及經典演算法
