Spark 的一大好處就是能夠經過增長機器數量並使用集羣模式運行,來擴展程序的計算能力。好在編寫用於在集羣上並行執行的 Spark 應用所使用的 API 跟本地單機模式下的徹底同樣。也就是說,你能夠在小數據集上利用本地模式快速開發並驗證你的應用,而後無需修改代碼就能夠在大規模集羣上運行。shell
首先介紹分佈式 Spark 應用的運行環境架構,而後討論在集羣上運行 Spark 應用時的一些配置項。Spark 能夠在各類各樣的集羣管理器(Hadoop YARN、Apache Mesos,還有Spark 自帶的獨立集羣管理器)上運行,因此 Spark 應用既可以適應專用集羣,又能用於共享的雲計算環境。緩存
在分佈式環境下,Spark 集羣採用的是主 / 從結構。在一個 Spark 集羣中,有一個節點負責中央協調,調度各個分佈式工做節點。這個中央協調節點被稱爲驅動器(Driver)節點,與之對應的工做節點被稱爲執行器(executor)節點。驅動器節點能夠和大量的執行器節點進行通訊,它們也都做爲獨立的 Java 進程運行。驅動器節點和全部的執行器節點一塊兒被稱爲一個 Spark 應用(application)。網絡
Spark 應用經過一個叫做集羣管理器(Cluster Manager)的外部服務在集羣中的機器上啓動。Spark 自帶的集羣管理器被稱爲獨立集羣管理器。Spark 也能運行在 Hadoop YARN 和Apache Mesos 這兩大開源集羣管理器上。架構
Spark 驅動器是執行你的程序中的 main() 方法的進程。它執行用戶編寫的用來建立SparkContext、建立 RDD,以及進行 RDD 的轉化操做和行動操做的代碼。其實,當你啓動 Spark shell 時,你就啓動了一個 Spark 驅動器程序(相信你還記得,Spark shell 老是會預先加載一個叫做 sc 的 SparkContext 對象)。驅動器程序一旦終止,Spark 應用也就結束了。app
驅動器程序在 Spark 應用中有下述兩個職責。
• 把用戶程序轉爲任務
Spark 驅動器程序負責把用戶程序轉爲多個物理執行的單元,這些單元也被稱爲任務(task)。從上層來看,全部的 Spark 程序都遵循一樣的結構:程序從輸入數據建立一系列 RDD,再使用轉化操做派生出新的 RDD,最後使用行動操做收集或存儲結果 RDD中的數據。
Spark 程序實際上是隱式地建立出了一個由操做組成的邏輯上的有向無環圖(Directed Acyclic Graph,簡稱 DAG)。當驅動器程序運行時,它會把這個邏輯圖轉爲物理執行計劃。
Spark 會對邏輯執行計劃做一些優化,好比將連續的映射轉爲流水線化執行,將多個操做合併到一個步驟中等。這樣 Spark 就把邏輯計劃轉爲一系列步驟(stage)。而每一個步驟又由多個任務組成。這些任務會被打包並送到集羣中。任務是 Spark 中最小的工做單元,用戶程序一般要啓動成百上千的獨立任務。
• 爲執行器節點調度任務
有了物理執行計劃以後,Spark 驅動器程序必須在各執行器進程間協調任務的調度。執行器進程啓動後,會向驅動器進程註冊本身。所以,驅動器進程始終對應用中全部的執行器節點有完整的記錄。每一個執行器節點表明一個可以處理任務和存儲 RDD 數據的進程。
Spark 驅動器程序會根據當前的執行器節點集合,嘗試把全部任務基於數據所在位置分配給合適的執行器進程。當任務執行時,執行器進程會把緩存數據存儲起來,而驅動器進程一樣會跟蹤這些緩存數據的位置,而且利用這些位置信息來調度之後的任務,以儘可能減小數據的網絡傳輸。
驅動器程序會將一些 Spark 應用的運行時的信息經過網頁界面呈現出來,默認在端口4040 上。好比,在本地模式下,訪問 http://localhost:4040 就能夠看到這個網頁了。分佈式
Spark 執行器節點是一種工做進程,負責在 Spark 做業中運行任務,任務間相互獨立。Spark 應用啓動時,執行器節點就被同時啓動,而且始終伴隨着整個 Spark 應用的生命週期而存在。若是有執行器節點發生了異常或崩潰,Spark 應用也能夠繼續執行。執行器進
程有兩大做用:第一,它們負責運行組成 Spark 應用的任務,並將結果返回給驅動器進程;第二,它們經過自身的塊管理器(Block Manager)爲用戶程序中要求緩存的 RDD 提供內存式存儲。RDD 是直接緩存在執行器進程內的,所以任務能夠在運行時充分利用緩存數據加速運算。
在本地模式下,Spark 驅動器程序和各執行器程序在同一個 Java 進程中運行。這是一個特例;執行器程序一般都運行在專用的進程中。工具
不論你使用的是哪種集羣管理器,你均可以使用 Spark 提供的統一腳本 spark-submit 將你的應用提交到那種集羣管理器上。經過不一樣的配置選項, spark-submit 能夠鏈接到相應的集羣管理器上,並控制應用所使用的資源數量。在使用某些特定集羣管理器時, spark-submit 也能夠將驅動器節點運行在集羣內部(好比一個 YARN 的工做節點)。但對於其餘的集羣管理器,驅動器節點只能被運行在本地機器上。oop
在集羣上運行 Spark 應用的詳細過程大數據
(1) 用戶經過 spark-submit 腳本提交應用。
(2) spark-submit 腳本啓動驅動器程序,調用用戶定義的 main() 方法。
(3) 驅動器程序與集羣管理器通訊,申請資源以啓動執行器節點。
(4) 集羣管理器爲驅動器程序啓動執行器節點。
(5) 驅動器進程執行用戶應用中的操做。根據程序中所定義的對 RDD 的轉化操做和行動操做,驅動器節點把工做以任務的形式發送到執行器進程。
(6) 任務在執行器程序中進行計算並保存結果。
(7) 若是驅動器程序的 main() 方法退出,或者調用了 SparkContext.stop() ,驅動器程序會終止執行器進程,而且經過集羣管理器釋放資源。優化
Spark 爲各類集羣管理器提供了統一的工具來提交做業,這個工具是 spark-submit 。在調用 spark-submit 時除了腳本或 JAR 包的名字以外沒有別的參數,那麼這個 Spark程序只會在本地執行。當咱們但願將應用提交到 Spark 獨立集羣上的時候,除了腳本或 JAR 包的名字以外還必須有別的參數。例如:
bin/spark-submit --master spark://host:7077 --executor-memory 10g my_script.py
--master 標記指定要鏈接的集羣 URL;下表給出了spark-submit 的 --master 標記能夠接收的值
除了集羣 URL, spark-submit 還提供了各類選項,可讓你控制應用每次運行的各項細節。這些選項主要分爲兩類。第一類是調度信息,好比你但願爲做業申請的資源量。第二類是應用的運行時依賴,好比須要部署到全部工做節點上的庫和文件。下面列出 spark-submit 的一些常見標記。
還能夠運行 spark-submit --help 列出全部能夠接收的標記。
Spark 能夠運行在各類集羣管理器上,並經過集羣管理器訪問集羣中的機器。若是你只想在一堆機器上運行 Spark,那麼自帶的獨立模式是部署該集羣最簡單的方法。然而,若是你有一個須要與別的分佈式應用共享的集羣(好比既能夠運行 Spark 做業又能夠運行Hadoop MapReduce 做業),Spark 也能夠運行在兩個普遍使用的集羣管理器——HadoopYARN 與 Apache Mesos 上面。最後,在把 Spark 部署到 Amazon EC2 上時,Spark 有個自帶的腳本能夠啓動獨立模式集羣以及各類相關服務。
Spark 所支持的各類集羣管理器爲咱們提供了部署應用的多種選擇。若是你須要從零開始部署,正在權衡各類集羣管理器,咱們推薦以下一些準則。
• 若是是從零開始,能夠先選擇獨立集羣管理器。獨立模式安裝起來最簡單,並且若是你只是使用 Spark 的話,獨立集羣管理器提供與其餘集羣管理器徹底同樣的所有功能。
• 若是你要在使用 Spark 的同時使用其餘應用,或者是要用到更豐富的資源調度功能(例如隊列),那麼 YARN 和 Mesos 都能知足你的需求。而在這二者中,對於大多數Hadoop 發行版來講,通常 YARN 已經預裝好了。
• Mesos 相對於 YARN 和獨立模式的一大優勢在於其細粒度共享的選項,該選項能夠將相似 Spark shell 這樣的交互式應用中的不一樣命令分配到不一樣的 CPU 上。所以這對於多用戶同時運行交互式 shell 的用例更有用處。
• 在任什麼時候候,最好把 Spark 運行在運行 HDFS 的節點上,這樣能快速訪問存儲。你能夠自行在一樣的節點上安裝 Mesos 或獨立集羣管理器。若是使用 YARN 的話,大多數發行版已經把 YARN 和 HDFS 安裝在了一塊兒。
這篇博文主要來自《Spark快速大數據分析》這本書裏面的第七章,內容有刪減。