本節書摘來自華章計算機《spark與hadoop大資料分析》一書中的第3章,第3.6節,作者:文卡特·安卡姆(venkat ankam) 更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。
在本章其他部分(在 pyspark shell 和應用程式中),我們已經在 spark 的 standalone 資料總管中執行過 spark 應用程式。讓我們嘗試了解這些叢集資料總管互相之間有什麼不同,以及它們該在什麼情況下使用。
3.6.1 本地和叢集模式
在繼續講解叢集資料總管之前,讓我們來了解叢集模式與本地模式的差別。
當跨叢集執行代碼時,了解變量和方法的範圍和生命周期非常重要。讓我們看一個使用 foreach 動作的例子:
在本地模式下,前面的代碼執行正常,因為計數器(counter)變量和 rdd 在相同的記憶體空間(單個 jvm)裡。
在叢集模式下,計數器 counter 的值永遠不會改變,并且始終保持為 0。在叢集模式下,spark 會計算出帶有變量和方法的閉包,并将它們發送到執行程序。當執行程序執行這個 foreach 函數時,它指向的是執行程序上的計數器的新副本。執行程序不能通路驅動程序上的計數器。是以,每次執行此操作時,本地計數器都會遞增,但不會傳回到驅動程序。要在叢集模式下解決此問題,需要為每個閉包建立一個單獨的變量副本,或使用一個累加變量。
3.6.2 叢集資料總管
你可以在四種不同的模式下運作 spark 應用程式:
本地模式:在本地模式下,所有程序在單個 jvm 中運作,并且不會像在叢集模式下那樣進行資料的混排。
如果指定了 spark.master(或--master)配置屬性,應用程式會在它指定的一個叢集資料總管上運作,運作在用戶端還是叢集模式則取決于指定的 --deploy-mode 參數。
standalone 模式:将 spark 應用程式送出到 spark 的内置叢集管理器。
yarn 模式:将 spark 應用程式送出到 yarn 資料總管。
mesos 模式:将 spark 應用程式送出到 mesos 叢集管理器。
standalone
預設情況下,以 standalone模式送出的應用程式會占用叢集的所有 cpu 核心(根據 spark.deploy.defaultcores 屬性),并給每個執行程序配置設定 1g 記憶體。在多個應用程式的環境中,重要的是限制每個應用程式占用的資源上限。限制 cpu 核心占用的方式可以利用 spark-submit 的 --total-executor-cores 參數,或 spark 配置檔案中的 spark.cores.max 參數。要限制占用的記憶體,可以利用 spark-submit 的 --executor-memory 參數,或 spark 配置檔案中的 spark.executor.memory 參數。
在本示例中,我們使用一個 20 節點的叢集,每個節點有 4 個 cpu 核心:
在沒有指定參數的情況下,一個應用程式将啟動 20 個具有 4 個 cpu 核心和 1 gb 記憶體的執行程序。
--executor-memory 1g 和 --total-executor-cores 8:spark 将啟動 8 個執行程序,每個執行程序有 1 gb 的記憶體。
spark conf 裡的 spark.deploy.spreadout 設為 false:spark 将啟動 2 個執行程序,每個執行程序具有 1 gb 的記憶體和 4 個 cpu 核心。
yarn
應用程式可以用 --master yarn-client 參數送出,即為用戶端模式;或用 --master yarn-cluster 參數送出,即為叢集模式。在 yarn 模式下,你可以指定所需的執行程序數與 cpu 核心數,這可以對照 spark 的 standalone 主機中的 -total-executor-cores 參數。
--num-executors 參數控制的是配置設定執行程序的數量(預設值為2)。該屬性在配置中可以用 spark.executor.instances 來設定。
--executor-memory 參數對應每個執行程序的記憶體數量。
--executor-cores 對應的是每個執行程序的 cpu 核心數量。
在本示例中,我們使用了一個 20 節點的叢集,每個節點有 4 個 cpu 核心:
如果沒有指定參數,應用程式将啟動 2 個執行程序,每個執行程序有 1 個 cpu 核心和 1 gb 記憶體。
--num-executors 8 --executor-memory 2g --executor-cores 4 :spark 将啟動 8 個執行程序,每個執行程序有 2 gb 記憶體和 4 個 cpu 核心。
下載下傳示例代碼
在本書的前言中講解了下載下傳代碼包的詳細步驟。請查閱。
動态資源配置設定
動态資源配置設定功能是在 spark 1.2 中引入的。應用程式可以把不會再用到的資源傳回給叢集,并在以後需要時再次請求它們。動态的資源配置設定可以有效率地控制叢集上的資源使用。如圖3-12 所示,由于存在運作較慢的節點(straggler)、排程、等待、空閑等情況,所有 spark 應用程式中配置設定和使用的資源都有很大的變化。
要啟用此功能,可以在應用程式中設定以下配置屬性:
spark.dynamicallocation.enabled
spark.dynamicallocation.minexecutors
spark.dynamicallocation.maxexecutors
spark.dynamicallocation.initialexecutors
spark.shuffle.service.enabled
請注意,在啟用動态配置設定時,不要使用 spark.executor.instances(或 --num-executors)參數。如果兩者都使用,動态配置設定将被禁用,生效的會是 --num-executors 。

圖3-12 資源配置設定和資源使用情況
用戶端模式和叢集模式
在 yarn 用戶端模式下運作 spark 時,驅動程序在用戶端計算機上運作,應用管理器和執行程序在叢集上運作。每個 spark 執行程序會作為用戶端或叢集模式下的一個 yarn 容器運作。
在 yarn 叢集模式下,驅動程序在應用管理器中運作。是以,應用管理器負責運作驅動程序和從 yarn 資料總管請求資源。啟動應用程式的用戶端在應用程式的整個生命周期中并不需要一直介入。
yarn 叢集用于生産作業,而 yarn 用戶端模式用于互動模式,在這種模式下,你可以即時看到應用程式的輸出。
yarn 用戶端模式和叢集模式如圖3-13 所示。
mesos
apache mesos 是一個通用的叢集管理器,它可以在叢集上運作分析任務及長時間運作的服務(例如 web 應用程式或鍵值存儲)。請參閱以下示例用法:
圖3-13 yarn 的用戶端模式和叢集模式
mesos 中有兩種類型的排程模式:
細粒度:細粒度模式的表現和 yarn 類似。執行程序在執行任務時會對它們請求的 cpu 數量進行上下調整,是以運作多個執行程序的一台機器可以在它們之間動态地共享 cpu 資源。這是預設模式。
粗粒度:粗粒度模式的表現和 standalone 類似。spark 會預先為每個執行程序配置設定固定數量的 cpu,并且在應用程式結束之前不會釋放它們,即使執行程序目前沒有運作任務。你可以通過傳遞以下參數來啟用粗粒度模式:
該使用哪種資料總管
當在 hadoop 叢集上把 spark 和其他應用程式配套使用時,最好使用 yarn 來更好地共享資源。在無需擔心改善性能和共享資源的情況下,可以使用 standalone 管理器。mesos 和 yarn 提供了類似的資源共享功能。在 hadoop 叢集上,使用 yarn 是合适的,因為 hadoop 的所有其他架構都與 yarn 內建了。對于非 hadoop 叢集,使用 mesos 也是可行的。