Spark 獨立模式

除了在 Mesos 或 YARN 叢集管理員上執行外,Spark 還提供了一個簡單的獨立部署模式。您可以手動啟動獨立叢集,方法是手動啟動主控和工作節點,或使用我們提供的 啟動腳本。您也可以在單一機器上執行這些守護程式以進行測試。

安全性

安全性功能(例如驗證)預設未啟用。在部署開放給網際網路或不受信任網路的叢集時,保護叢集存取權非常重要,以防止未經授權的應用程式在叢集上執行。在執行 Spark 之前,請參閱 Spark 安全性 和本文檔中的特定安全性區段。

在叢集中安裝 Spark 獨立模式

若要安裝 Spark 獨立模式,您只需將編譯版本的 Spark 放置在叢集上的每個節點上。您可以取得每個版本的預先建置版本 Spark,或 自行建置

手動啟動叢集

您可以透過執行來啟動獨立主控伺服器

./sbin/start-master.sh

啟動後,主控會為自己印出 spark://HOST:PORT URL,您可以使用此 URL 將工作節點連線到主控,或將其傳遞為 SparkContext 的「主控」引數。您也可以在主控的網路使用者介面上找到此 URL,預設為 https://127.0.0.1:8080

同樣地,您可以啟動一個或多個工作節點,並透過以下方式將它們連線到主控

./sbin/start-worker.sh <master-spark-URL>

啟動工作節點後,請查看主控的網路使用者介面(預設為 https://127.0.0.1:8080)。您應該會在那裡看到列出的新節點,以及其 CPU 和記憶體數量(減去留給作業系統的一吉位元組)。

最後,下列設定選項可以傳遞給主控和工作節點

引數意義
-h HOST--host HOST 要監聽的主機名稱
-i HOST--ip HOST 要監聽的主機名稱(已過時,請使用 -h 或 --host)
-p PORT--port PORT 服務要監聽的連接埠(預設:主控為 7077,工作節點為隨機)
--webui-port PORT 網路使用者介面的連接埠(預設:主控為 8080,工作節點為 8081)
-c CORES--cores CORES 允許 Spark 應用程式在機器上使用的總 CPU 核心數(預設:所有可用核心);僅在工作節點上
-m MEM--memory MEM 允許 Spark 應用程式在機器上使用的總記憶體量,格式類似於 1000M 或 2G(預設:機器總 RAM 減去 1 GiB);僅在工作節點上
-d DIR--work-dir DIR 用於暫存空間和作業輸出記錄的目錄(預設:SPARK_HOME/work);僅在工作節點上
--properties-file FILE 要載入的客製化 Spark 屬性檔路徑(預設:conf/spark-defaults.conf)

叢集啟動指令碼

若要使用啟動指令碼啟動 Spark 獨立叢集,您應該在 Spark 目錄中建立一個名為 conf/workers 的檔案,其中必須包含您打算啟動 Spark 工作節點的所有機器主機名稱,每行一個。如果 conf/workers 不存在,啟動指令碼會預設為單一機器(localhost),這對於測試很有用。請注意,主機機器會透過 ssh 存取每個工作節點機器。預設情況下,ssh 會並行執行,並需要設定無密碼(使用私密金鑰)存取。如果您沒有無密碼設定,您可以設定環境變數 SPARK_SSH_FOREGROUND,並為每個工作節點提供密碼。

設定好這個檔案後,您可以使用以下 shell 指令碼啟動或停止叢集,這些指令碼是根據 Hadoop 的部署指令碼,可在 SPARK_HOME/sbin 中取得

請注意,這些腳本必須在您要執行 Spark 主控端點的機器上執行,而不是您的本機機器。

您可以在 conf/spark-env.sh 中設定環境變數,以選擇性地進一步設定叢集。透過 conf/spark-env.sh.template 開始建立這個檔案,並將其複製到所有工作機,以讓設定生效。下列設定可用

環境變數意義
SPARK_MASTER_HOST 將主控端點繫結到特定主機名稱或 IP 位址,例如公用位址。
SPARK_MASTER_PORT 在不同埠上啟動主控端點(預設:7077)。
SPARK_MASTER_WEBUI_PORT 主控端點網頁使用者介面的埠(預設:8080)。
SPARK_MASTER_OPTS 僅適用於主控端點的設定屬性,格式為「-Dx=y」(預設:無)。請參閱下方,以取得可能的選項清單。
SPARK_LOCAL_DIRS Spark 中用於「暫存」空間的目錄,包括儲存在磁碟上的映射輸出檔案和 RDD。這應該是在您系統中的快速本機磁碟上。它也可以是不同磁碟上多個目錄的逗號分隔清單。
SPARK_WORKER_CORES 允許 Spark 應用程式在機器上使用的核心總數(預設:所有可用核心)。
SPARK_WORKER_MEMORY 允許 Spark 應用程式在機器上使用的記憶體總量,例如 1000m2g(預設:總記憶體減去 1 GiB);請注意,每個應用程式的個別記憶體是使用其 spark.executor.memory 屬性設定的。
SPARK_WORKER_PORT 在特定埠上啟動 Spark 工作器(預設:隨機)。
SPARK_WORKER_WEBUI_PORT 工作器網頁使用者介面的埠(預設:8081)。
SPARK_WORKER_DIR 執行應用程式的目錄,其中將包括記錄和暫存空間(預設:SPARK_HOME/work)。
SPARK_WORKER_OPTS 僅適用於工作器的設定屬性,格式為「-Dx=y」(預設:無)。請參閱下方,以取得可能的選項清單。
SPARK_DAEMON_MEMORY 分配給 Spark 主控端點和工作器守護程式本身的記憶體(預設:1g)。
SPARK_DAEMON_JAVA_OPTS Spark 主控端點和工作器守護程式本身的 JVM 選項,格式為「-Dx=y」(預設:無)。
SPARK_DAEMON_CLASSPATH Spark 主控端點和工作器守護程式本身的類別路徑(預設:無)。
SPARK_PUBLIC_DNS Spark master 和工作節點的公用 DNS 名稱(預設:無)。

注意:啟動腳本目前不支援 Windows。要在 Windows 上執行 Spark 群集,請手動啟動 master 和工作節點。

SPARK_MASTER_OPTS 支援下列系統屬性

屬性名稱預設值意義版本
spark.master.ui.port 8080 指定 Master Web UI 端點的連接埠號碼。 1.1.0
spark.master.ui.decommission.allow.mode LOCAL 指定 Master Web UI 的 /workers/kill 端點的行為。可能的選項為:LOCAL 表示允許來自執行 Master 的機器本機 IP 的此端點,DENY 表示完全停用此端點,ALLOW 表示允許從任何 IP 呼叫此端點。 3.1.0
spark.master.rest.enabled false 是否使用 Master REST API 端點。 1.3.0
spark.master.rest.port 6066 指定 Master REST API 端點的連接埠號碼。 1.3.0
spark.deploy.retainedApplications 200 要顯示的已完成應用程式的最大數目。較舊的應用程式將從 UI 中移除以維持此限制。
0.8.0
spark.deploy.retainedDrivers 200 要顯示的已完成驅動程式的最大數目。較舊的驅動程式將從 UI 中移除以維持此限制。
1.1.0
spark.deploy.spreadOut true 獨立式群集管理員是否應將應用程式分散到各節點,或嘗試將它們整合到盡可能少的節點上。分散通常較適合 HDFS 中的資料區域性,但整合則對於運算密集的工作負載較有效率。
0.6.1
spark.deploy.defaultCores (無限) 如果應用程式未設定 spark.cores.max,則在 Spark 的獨立模式中提供給應用程式的預設核心數目。如果未設定,則應用程式會永遠取得所有可用的核心,除非它們自行設定 spark.cores.max。在共用群集中將此值設為較低,以防止使用者預設擷取整個群集。
0.9.0
spark.deploy.maxExecutorRetries 10 在獨立式群集管理員移除有問題的應用程式之前,可連續發生的執行器失敗最大次數限制。如果應用程式有任何正在執行的執行器,則絕不會移除該應用程式。如果應用程式連續發生超過 spark.deploy.maxExecutorRetries 次失敗,且在這些失敗之間沒有執行器成功開始執行,且應用程式沒有正在執行的執行器,則獨立式群集管理員會移除該應用程式並將其標示為失敗。若要停用此自動移除功能,請將 spark.deploy.maxExecutorRetries 設定為 -1
1.6.3
spark.worker.timeout 60 如果獨立式部署 master 沒有收到心跳,則視為工作節點遺失的秒數。 0.6.2
spark.worker.resource.{name}.amount (無) 在工作節點上使用的特定資源量。 3.0.0
spark.worker.resource.{name}.discoveryScript (無) 資源發現腳本路徑,用於在工作節點啟動時尋找特定資源。腳本的輸出應格式化為 ResourceInformation 類別。 3.0.0
spark.worker.resourcesFile (無) 資源檔案路徑,用於在工作節點啟動時尋找各種資源。資源檔案的內容應格式化為 [{"id":{"componentName": "spark.worker", "resourceName":"gpu"}, "addresses":["0","1","2"]}]。如果在資源檔案中找不到特定資源,將使用發現腳本尋找該資源。如果發現腳本也找不到資源,工作節點將無法啟動。 3.0.0

SPARK_WORKER_OPTS 支援下列系統屬性

屬性名稱預設值意義版本
spark.worker.cleanup.enabled false 啟用工作節點/應用程式目錄的定期清理。請注意,這只會影響獨立模式,因為 YARN 的運作方式不同。只有已停止應用程式的目錄會被清理。如果 spark.shuffle.service.db.enabled 為「true」,應該啟用此功能 1.0.0
spark.worker.cleanup.interval 1800 (30 分鐘) 控制工作節點清理本地機器上舊應用程式工作目錄的間隔(以秒為單位)。 1.0.0
spark.worker.cleanup.appDataTtl 604800 (7 天,7 * 24 * 3600) 保留每個工作節點上應用程式工作目錄的秒數。這是一個生存時間 (Time To Live),應取決於您擁有的可用磁碟空間量。應用程式記錄和 JAR 會下載到每個應用程式工作目錄。隨著時間推移,工作目錄會快速填滿磁碟空間,特別是在您非常頻繁地執行工作時。 1.0.0
spark.shuffle.service.db.enabled true 將外部 Shuffle 服務狀態儲存在本地磁碟上,以便在重新啟動外部 Shuffle 服務時,它會自動重新載入目前執行緒的資訊。這只會影響獨立模式(yarn 總是啟用此行為)。您也應該啟用 spark.worker.cleanup.enabled,以確保最終清理狀態。此設定可能會在未來移除。 3.0.0
spark.shuffle.service.db.backend LEVELDB spark.shuffle.service.db.enabled 為 true 時,使用者可以使用此設定來指定 Shuffle 服務狀態儲存中使用的磁碟儲存類型。此設定目前支援 `LEVELDB` 和 `ROCKSDB`,預設值為 `LEVELDB`。`LevelDB/RocksDB` 中的原始資料儲存不會自動轉換為其他類型的儲存。 3.4.0
spark.storage.cleanupFilesAfterExecutorExit true 啟用清理執行器結束後工作目錄中的非洗牌檔案(例如 temp. 洗牌區塊、快取的 RDD/廣播區塊、溢出檔案等)。請注意,這與 `spark.worker.cleanup.enabled` 不同,因為這會啟用清理已中斷執行器的本地目錄中的非洗牌檔案,而 `spark.worker.cleanup.enabled` 會啟用清理已停止和逾時應用程式的所有檔案/子目錄。這只會影響獨立模式,未來可以新增對其他叢集管理員的支援。 2.4.0
spark.worker.ui.compressedLogFileLengthCacheSize 100 對於壓縮的日誌檔案,只能透過解壓縮檔案來計算未壓縮的檔案。Spark 會快取壓縮日誌檔案的未壓縮檔案大小。此屬性會控制快取大小。 2.0.2

資源配置和組態概觀

請務必閱讀 組態頁面 上的「自訂資源排程和組態概觀」區段。本區段只討論資源排程中 Spark 獨立模式的特定面向。

Spark 獨立模式有 2 個部分,第一個是設定工作人員的資源,第二個是特定應用程式的資源配置。

使用者必須設定工作人員,讓工作人員具備一組可用的資源,以便將這些資源分配給執行器。spark.worker.resource.{resourceName}.amount 用於控制工作人員分配的每個資源數量。使用者還必須指定 spark.worker.resourcesFilespark.worker.resource.{resourceName}.discoveryScript,以指定工作人員如何找出其分配的資源。請參閱上述每個說明,以查看哪種方法最適合您的設定。

第二個部分是在 Spark 獨立模式上執行應用程式。與標準 Spark 資源組態唯一的特殊情況是在用戶端模式下執行驅動程式時。對於用戶端模式中的驅動程式,使用者可以使用 spark.driver.resourcesFilespark.driver.resource.{resourceName}.discoveryScript 指定其使用的資源。如果驅動程式與其他驅動程式在同一主機上執行,請確保資源檔案或偵測指令碼只會傳回與在同一節點上執行的其他驅動程式不衝突的資源。

請注意,使用者在提交應用程式時不需要指定偵測指令碼,因為工作人員會以其分配給執行器的資源啟動每個執行器。

將應用程式連接到叢集

若要在 Spark 叢集上執行應用程式,只需將主控站的 spark://IP:PORT URL 傳遞給 SparkContext 建構函式

若要在叢集上執行互動式 Spark shell,請執行下列指令

./bin/spark-shell --master spark://IP:PORT

您也可以傳遞一個選項 --total-executor-cores <numCores> 來控制 spark-shell 在叢集上使用的核心數。

用戶端屬性

Spark 應用程式支援以下特定於獨立模式的組態屬性

屬性名稱預設值意義版本
spark.standalone.submit.waitAppCompletion false 在獨立叢集模式中,控制用戶端是否等到應用程式完成後才結束。如果設為 true,用戶端程序會持續運作並輪詢驅動程式的狀態。否則,用戶端程序會在提交後結束。 3.1.0

啟動 Spark 應用程式

Spark 協定

The spark-submit 程式碼 提供最直接的方式將編譯的 Spark 應用程式提交到叢集。對於獨立叢集,Spark 目前支援兩種部署模式。在 client 模式中,驅動程式會在與提交應用程式的用戶端相同的程序中啟動。然而,在 cluster 模式中,驅動程式會從叢集內的一個工作程序中啟動,而用戶端程序會在履行提交應用程式的責任後立即結束,而不會等到應用程式完成。

如果您的應用程式是透過 Spark 提交啟動的,則應用程式 jar 會自動分發到所有工作節點。對於應用程式依賴的任何其他 jar,您應該透過 --jars 旗標指定它們,並使用逗號作為分隔符 (例如 --jars jar1,jar2)。若要控制應用程式的組態或執行環境,請參閱 Spark 組態

此外,獨立 cluster 模式支援在應用程式以非零退出碼結束時自動重新啟動它。若要使用此功能,您可以在啟動應用程式時將 --supervise 旗標傳遞給 spark-submit。然後,如果您希望終止一個重複失敗的應用程式,您可以透過

./bin/spark-class org.apache.spark.deploy.Client kill <master url> <driver ID>

您可以在獨立主控台網路使用者介面中透過 http://<master url>:8080 找到驅動程式 ID。

REST API

如果 spark.master.rest.enabled 已啟用,Spark 主控台會透過 http://[host:port]/[version]/submissions/[action] 提供額外的 REST API,其中 host 是主控台主機,而 port 是由 spark.master.rest.port 指定的埠號 (預設值:6066),而 version 是協定版本,目前為 v1,而 action 是下列支援的動作之一。

指令說明HTTP 方法版本
建立 透過「叢集」模式建立 Spark 驅動程式。 POST 1.3.0
終止 終止單一 Spark 驅動程式。 POST 1.3.0
狀態 檢查 Spark 工作的狀態。 GET 1.3.0

以下是使用 pi.py 和 REST API 的 curl CLI 命令範例。

$ curl -XPOST http://IP:PORT/v1/submissions/create \
--header "Content-Type:application/json;charset=UTF-8" \
--data '{
  "appResource": "",
  "sparkProperties": {
    "spark.master": "spark://master:7077",
    "spark.app.name": "Spark Pi",
    "spark.driver.memory": "1g",
    "spark.driver.cores": "1",
    "spark.jars": ""
  },
  "clientSparkVersion": "",
  "mainClass": "org.apache.spark.deploy.SparkSubmit",
  "environmentVariables": { },
  "action": "CreateSubmissionRequest",
  "appArgs": [ "/opt/spark/examples/src/main/python/pi.py", "10" ]
}'

以下是 REST API 針對上述 建立 要求的回應。

{
  "action" : "CreateSubmissionResponse",
  "message" : "Driver successfully submitted as driver-20231124153531-0000",
  "serverSparkVersion" : "3.5.1",
  "submissionId" : "driver-20231124153531-0000",
  "success" : true
}

資源排程

獨立叢集模式目前僅支援應用程式的簡單 FIFO 排程器。不過,若要允許多個同時使用者,您可以控制每個應用程式將使用的最大資源數量。預設情況下,它將取得叢集中的所有核心,這只有在您一次只執行一個應用程式時才有意義。您可以透過在 SparkConf 中設定 spark.cores.max 來限制核心數量。例如

val conf = new SparkConf()
  .setMaster(...)
  .setAppName(...)
  .set("spark.cores.max", "10")
val sc = new SparkContext(conf)

此外,您可以在叢集主控處理序上設定 spark.deploy.defaultCores,以變更未將 spark.cores.max 設定為小於無限大的應用程式的預設值。請將下列內容新增至 conf/spark-env.sh

export SPARK_MASTER_OPTS="-Dspark.deploy.defaultCores=<value>"

這在使用者可能未個別設定最大核心數量的共用叢集上很有用。

執行器排程

分配給每個執行器的核心數量是可以設定的。當 spark.executor.cores 明確設定時,如果工作器有足夠的核心和記憶體,則可能會在同一個工作器上啟動來自同一個應用程式的多個執行器。否則,每個執行器預設會取得工作器上所有可用的核心,這種情況下,在一個單一排程反覆運算期間,每個工作器上可能只會啟動一個執行器。

階段層級排程概述

獨立模式支援階段層級排程

注意事項

動態資源配置 中所述,如果在啟用動態配置時未明確指定每個執行器的核心,Spark 可能會取得比預期多得多的執行器。因此,建議在使用階段層級排程時,明確設定每個資源設定檔的執行器核心。

監控和記錄

Spark 的獨立模式提供一個基於 Web 的使用者介面來監控叢集。主控程式和每個工作器都有自己的 Web UI,用於顯示叢集和工作統計資料。預設情況下,您可以在 8080 埠存取主控程式的 Web UI。埠可以透過設定檔或命令列選項變更。

此外,每個工作的詳細記錄輸出也會寫入每個工作器節點的工作目錄(預設為 SPARK_HOME/work)。您會看到每個工作有兩個檔案,stdoutstderr,其中包含寫入其主控台的所有輸出。

與 Hadoop 並行執行

您可以在現有的 Hadoop 叢集上執行 Spark,只要在同一台機器上將其作為一個獨立服務啟動即可。若要從 Spark 存取 Hadoop 資料,請使用 hdfs:// URL(通常為 hdfs://<namenode>:9000/path,但您可以在 Hadoop Namenode 的 Web UI 中找到正確的 URL)。或者,您可以為 Spark 設定一個獨立叢集,並讓它透過網路存取 HDFS;這會比磁碟本機存取慢,但如果您仍在同一個區域網路中執行(例如,您在擁有 Hadoop 的每個機架上放置幾台 Spark 機器),這可能不是問題。

設定網路安全連接埠

一般來說,Spark 叢集及其服務不會部署在公用網際網路上。它們通常是私人服務,而且只能在部署 Spark 的組織網路中存取。應該將對 Spark 服務使用的主機和埠的存取限制為需要存取這些服務的來源主機。

這對於使用獨立資源管理程式的叢集特別重要,因為它們不支援其他資源管理程式所支援的細緻存取控制。

如需設定的埠的完整清單,請參閱 安全性頁面

高可用性

預設情況下,獨立排程叢集具有復原工作器故障的能力(只要 Spark 本身具有透過將工作移至其他工作器來復原工作的復原能力)。不過,排程器會使用主控程式來做出排程決策,而這(預設情況下)會產生單一故障點:如果主控程式發生故障,就無法建立新的應用程式。為了避免這種情況,我們有兩種高可用性方案,詳情如下。

使用 ZooKeeper 的備用主控

概觀

利用 ZooKeeper 提供領導者選舉和部分狀態儲存,您可以在連接到相同 ZooKeeper 執行個體的叢集中啟動多個主控程式。其中一個將被選為「領導者」,而其他則會保持待命模式。如果目前的領導者終止,將會選出另一個主控程式,復原舊主控程式的狀態,然後繼續排程。整個復原程序(從第一個領導者終止的時間開始)應會花費 1 到 2 分鐘。請注意,此延遲只會影響排程新的應用程式,在主控程式故障轉移期間已經執行的應用程式不受影響。

在此處瞭解有關 ZooKeeper 入門的更多資訊。

設定

若要啟用此復原模式,您可以透過設定 spark.deploy.recoveryMode 和相關的 spark.deploy.zookeeper.* 設定,在 spark-env 中設定 SPARK_DAEMON_JAVA_OPTS。如需有關這些設定的更多資訊,請參閱設定文件

可能的問題:如果您的叢集中有多個主控程式,但未正確設定主控程式以使用 ZooKeeper,則主控程式將無法彼此發現,並認為自己都是領導者。這不會導致叢集狀態正常(因為所有主控程式都會獨立排程)。

詳細資料

在設定 ZooKeeper 叢集後,啟用高可用性非常簡單。只需在不同的節點上啟動多個主控程式程序,並使用相同的 ZooKeeper 設定(ZooKeeper URL 和目錄)。主控程式可以隨時新增和移除。

若要排程新的應用程式或將工作器新增到叢集,他們需要知道目前領導者的 IP 位址。這可以透過傳遞主控程式清單來達成,您過去會傳遞單一主控程式。例如,您可能會啟動 SparkContext 指向 spark://host1:port1,host2:port2。這會導致您的 SparkContext 嘗試向兩個主控程式註冊,如果 host1 終止,此設定仍然正確,因為我們會找到新的領導者 host2

「向主控程式註冊」和一般操作之間有重要的區別。在啟動時,應用程式或工作器需要能夠找到目前的領導者主控程式並向其註冊。然而,一旦成功註冊,它就會「在系統中」(即儲存在 ZooKeeper 中)。如果發生故障轉移,新的領導者將會連絡所有先前註冊的應用程式和工作器,以通知他們領導者變更,因此他們甚至不需要在啟動時知道新的主控程式的存在。

由於此屬性,隨時都能建立新的主控程式,而您唯一需要擔憂的是,新的應用程式和工作人員在主控程式成為領導者時,是否能找到它並註冊。一旦註冊,您就不用再擔心了。

使用本機檔案系統的單一節點復原

概觀

ZooKeeper 是達成生產等級高可用性的最佳方式,但如果您只想在主控程式當機時能夠重新啟動它,FILESYSTEM 模式就能滿足您的需求。當應用程式和工作人員註冊時,它們會將足夠的狀態寫入所提供的目錄,以便在主控程式流程重新啟動時,它們可以復原。

設定

若要啟用此復原模式,您可以使用下列組態在 spark-env 中設定 SPARK_DAEMON_JAVA_OPTS

系統屬性意義版本
spark.deploy.recoveryMode 設定為 FILESYSTEM 以啟用單一節點復原模式 (預設值:NONE)。 0.8.1
spark.deploy.recoveryDirectory Spark 將儲存復原狀態的目錄,可從主控程式的角度存取。 0.8.1

詳細資料