1、組件版本
調度系統:DolphinScheduler1.2.1java
spark版本:2.3.2python
2、提交方式
spark在submit腳本里提交job的時候,常常會有這樣的警告web
Warning: Master yarn-cluster is deprecated since 2.0. Please use master "yarn" with specified deploy mode instead.
這是由於你用了yarn-cluster的方式:sql
spark-submit \ --master yarn-cluster \ --executor-cores 2 \ --num-executors 3 \ --executor-memory 4g \ --driver-memory 1g \ test_spark.py
其實yarn-cluster與yarn-client分爲兩部分,分別對應spark內部的參數master-deployMode
,不論你指定yarn-cluster仍是yarn-client,master的值在源碼裏面都強制置爲了YARN,在org.apache.spark.deploy.SparkSubmit
類中源代碼以下:shell
val clusterManager: Int = args.master match { case "yarn" => YARN case "yarn-client" | "yarn-cluster" => printWarning(s"Master ${args.master} is deprecated since 2.0." + " Please use master \"yarn\" with specified deploy mode instead.") YARN case m if m.startsWith("spark") => STANDALONE case m if m.startsWith("mesos") => MESOS case m if m.startsWith("k8s") => KUBERNETES case m if m.startsWith("local") => LOCAL case _ => printErrorAndExit("Master must either be yarn or start with spark, mesos, k8s, or local") -1 }
spark deployMode
的默認值是client
,可是在spark-submit腳本中,這個參數通常沒人會去指定,因此就用它的默認值了。當全部人都適應默認值的時候,問題來了,若是在spark-submit腳本中設置了--master yarn-clsuter
,源碼裏面會把deployMode
的值修改成cluster
,源代碼以下:apache
(args.master, args.deployMode) match { case ("yarn-cluster", null) => // 這裏把本來的默認值改爲了CLUSTER deployMode = CLUSTER args.master = "yarn" case ("yarn-cluster", "client") => printErrorAndExit("Client deploy mode is not compatible with master \"yarn-cluster\"") case ("yarn-client", "cluster") => printErrorAndExit("Cluster deploy mode is not compatible with master \"yarn-client\"") case (_, mode) => args.master = "yarn" }
簡言之,spark-submit腳本指定–master參數,實際決定了兩個值:網絡
設爲yarn/yarn-client時:yarn-client模式oop
設爲yarn-cluster時:yarn-cluster模式大數據
3、運行原理
yarn/yarn-client模式以下:ui
yarn-cluster模式以下:
很明顯,明面上惟一的區別就體如今driver在調度機器上仍是在yarn
4、分析過程
我用py寫了個簡單的spark程序,基本就是讀表、存表的操做
#!/usr/bin/env python3 from pyspark.sql import SparkSession spark = SparkSession.builder.master("yarn").enableHiveSupport().getOrCreate() df = spark.sql("select item_type,count(*) as num from dw_db.dw_recessw_minipage_items_h group by item_type") df.write.mode("overwrite").saveAsTable("dw_db.pyspark")
spark-submit腳本,--master
參數分別設置爲yarn
或yarn-master
source /etc/profile
spark-submit \
--master yarn 或 yarn-master \
--executor-cores 2 \
--num-executors 3 \
--executor-memory 4g \
--driver-memory 1g \
test_pyspark.py
以兩種模式分別運行後打開spark的web ui界面點擊Environment導航欄
分別把上面的Spark Properties和System Properties的全部參數配置拷貝出來放文件裏面,我這裏把兩種模式下的全部配置項拷出來以後去掉了全部相同配置對比圖以下:
能夠看到區別比較大的是spark.submit.deployMode
分別爲cluster
和client
,關鍵部分在下面的System Properties,裏面包含了運行spark-submit腳本的路徑和用戶,還有實際執行java程序的調用類都不一樣!
5、致命區別
-
yarn(yarn-client):
-
帶寬角度
這種模式因爲driver在你的調度機器上,若是調度機器不在yarn集羣機器上部署,driver與executor通訊會致使大量的帶寬流量產生,spark streaming實時程序或者程序比較多的狀況下,網絡帶寬會打滿撐爆,帶寬打滿的狀況下,連鎖反應的後果是集羣上全部任務都會拖慢,線上事故妥妥的!若是調度機器跟yarn同一集羣,推薦這種方式!也方便在調度系統上查看driver的日誌。
-
權限控制角度
在上圖中能夠看到System Properties的
user.name
是lijf,上面的代碼最後會有寫表的操做,寫hdfs的用戶也就是lijf,由於最後實際執行spark程序executor端的用戶就是lijf,控制hdfs讀寫權限只須要控制lijf用戶的讀寫權限就好了,這裏使用的是ranger作權限控制,很是方便。
-
-
yarn-cluster
-
帶寬角度
這種方式提交spark任務後,啓動driver的節點是yarn上的隨機節點,由AppMaster啓動,無需關注調度機器是否與yarn集羣部署在一塊。
-
權限控制角度
這種方式致命的缺點,能夠看到System Properties的
user.name
是yarn,意思是不管哪一個用戶提交spark任務,最後executor端讀寫hdfs都是以yarn的身份,因此集羣的權限管理根本無法控制!權限控制很差,刪庫跑路,完了別告訴我你是幹大數據的,線上事故妥妥的!固然,你也能夠想辦法去設置executor端的用戶,須要想辦法指定系統變量,基於DolphinScheduler本人目前還沒找到很好的方法去配置,可是基於與hadoop關係較好的oozie是能夠配置的,由於oozie調度任務自然的優點自己就是在yarn上運行,指定oozie的調度用戶即指定了運行時的系統用戶,從而把系統用戶傳給了executor。這裏控制的是hdfs文件的權限,不要與hive表權限混爲一談,hive表的權限是在drive端去操做catlog控制ddl操做。
-
6、總結
綜上所述,調度與yarn集羣共同機器部署,spark的–master參數置爲yarn是最佳配置,既不產生帶寬問題,也沒有權限控制問題。