Spark是怎麼進行資源任務和資源分配的?

任務調度機制

  1. Spark-submit啓動進程,初始化創建SparkContext
  2. SparkContext構建DAGSchedular和TaskSchedular
  3. 客戶端連接master申請註冊application 
  4. master接收application註冊申請,根據資源調度算法(FIFO、FAIR)在worker節點上啓動多個executor
  5. 通知worker啓動executor
  6. 所有啓動好的executor,反向註冊到TaskSchedular
  7. 此時各方面資源都準備好了,結束SparkContext初始化
  8. SparkContext開始執行處理業務邏輯,每執行到一個action算子,即創建一個job,並且把job提交給DAGSchedular
  9. DAGSchedular將job劃分成多個stage,劃分依據:寬依賴。每個stage對應一個TaskSet。並提交給TaskSchedular
  10. TaskSchedular將task任務,分發到Executor執行

 


Spark調度模式 FIFO和FAIR

【1】Spark中的調度模式主要有兩種:FIFO和FAIR。
【2】默認情況下Spark的調度模式是FIFO(先進先出),誰先提交誰先執行,後面的任務需要等待前面的任務執行。而FAIR(公平調度)模式支持在調度池中爲任務進行分組,不同的調度池權重不同,任務可以按照權重來決定執行順序。
【3】設置方式

val conf =new SparkConf().setMaster(...).setAppName(...)
conf.set("spark.scheduler.mode","FAIR")
val sc =newSparkContext(conf)

資源分配概述

  • spark的分配資源主要就是 executor、cpu per executor、memory per executor、driver memory 等的調節,在我們的生產環境中,提交spark作業時,用的spark-submit shell腳本,裏面調整對應的參數:
spark-submit \
--class cn.spark.sparktest.core.WordCountCluster \
--num-executors 3 \ 配置executor的數量
--driver-memory 100m \ 配置driver的內存(影響不大)
--executor-memory 100m \ 配置每個executor的內存大小
--executor-cores 3 \    配置每個executor的cpu core數量
/usr/local/SparkTest-0.0.1-SNAPSHOT-jar-with-dependencies.jar \

如何分配資源

  • 首先要了解你的機子的資源,多大的內存,多少個cpu core,就根據這個實際情況去設置,能使用多少資源,就儘量去調節到最大的大小(executor的數量,幾十個到上百個不等;executor內存;executor cpu core)。一個cpu對應2-3task合理
    • Standalone 模式
      • 如果每臺機器可用內存是4G,2個cpu core,20臺機器,
      • 那可以設置:20個executor,每個executor4G內存,2個cpu core(資源最大化利用)。
    • yarn 模式下
      • 根據spark要提交的資源隊列資源來考慮,如果所在隊列資源爲500G內存,100個cpu core。
      • 可以設置50個executor;每個executor10G內存2個cpu
  • 調節資源後,SparkContext,DAGScheduler,TaskScheduler,會將我們的算子,切割成大量的task,提交到Application的executor上面去執行。

分配資源策略

給application分配資源選擇worker(executor),現在有兩種策略:

  • 儘量的打散,即一個Application儘可能多的分配到不同的節點。這個可以通過設置spark.deploy.spreadOut來實現。默認值爲true,即儘量的打散。(默認)
  • 儘量的集中,即一個Application儘量分配到儘可能少的節點。

分配資源分析

  • 增加每個executor的cpu core,也是增加了執行的並行能力。原本20個executor,每個才2個cpu core。能夠並行執行的task數量,就是40個task。
    • 如果現在每個executor的cpu core,增加到了5個。能夠並行執行的task數量,就是100個task。執行的速度,提升了2.5倍。
    • 如果executor數量比較少,那麼能夠並行執行的task數量就比較少,就意味着,我們的Application的並行執行的能力就很弱。
      • 比如有3個executor,每個executor有2個cpu core,那麼同時能夠並行執行的task就是6個。6個執行完以後,再換下一批6個task。
    • 增加了executor數量以後,那麼就意味着能夠並行執行的task數量,也就變多了。比如原先是6個,現在可能可以並行執行10個,甚至20個,100個。那麼並行能力就比之前提升了數倍,數十倍。相應的,性能(執行的速度),也能提升數倍~數十倍。
  • 增加每個executor的內存量。增加了內存量以後,對性能的提升有幾點:
    • 如果需要對RDD進行cache,那麼更多的內存,就可以緩存更多的數據,將更少的數據寫入磁盤,甚至不寫入磁盤。減少了磁盤IO。
    • 對於shuffle操作,reduce端,會需要內存來存放拉取的數據並進行聚合。如果內存不夠,也會寫入磁盤。如果給executor分配更多內存以後,就有更少的數據,需要寫入磁盤,甚至不需要寫入磁盤。減少了磁盤IO,提升了性能。
    • 對於task的執行,可能會創建很多對象。如果內存比較小,可能會頻繁導致JVM堆內存滿了,然後頻繁GC,垃圾回收, GC和full GC。(速度很慢)。內存加大以後,帶來更少的GC,垃圾回收,避免了速度變慢,速度變快了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章