# Monitoring and Instrumentation
有幾種方法來監視 Spark 應用程序:Web UI,metrics 和外部工具。
# Web 界面
每個 SparkContext 都會啟動一個 Web UI,默認端口為 4040,顯示有關應用程序的有用信息。這包括:
* 調度器階段和任務的列表
* RDD 大小和內存使用的概要信息
* 環境信息
* 正在運行的執行器的信息
您可以通過在 Web 瀏覽器中打開 `http://<driver-node>:4040` 來訪問此界面。如果多個 SparkContexts 在同一主機上運行,則它們將綁定到連續的端口從 4040(4041,4042 等)開始。
請注意,默認情況下此信息僅適用于運行中的應用程序。要在事后還能通過 Web UI 查看,請在應用程序啟動之前,將 `spark.eventLog.enabled` 設置為 true。這配置 Spark 持久存儲以記錄 Spark 事件,再通過編碼該信息在 UI 中進行顯示。
## 事后查看
仍然可以通過 Spark 的歷史服務器構建應用程序的UI,只要應用程序的事件日志存在。您可以通過執行以下命令啟動歷史服務器:
```
./sbin/start-history-server.sh
```
默認情況下,會在 `http://<server-url>:18080` 創建一個 Web 界面,顯示未完成、完成以及其他嘗試的任務信息。
當使用 file-system 提供程序類(見下面 `spark.history.provider`)時,基本日志記錄目錄必須在`spark.history.fs.logDirectory`配置選項中提供,并且應包含每個代表應用程序的事件日志的子目錄。
Spark 任務本身必須配置啟用記錄事件,并將其記錄到相同共享的可寫目錄下。例如,如果服務器配置了日志目錄`hdfs://namenode/shared/spark-logs`,那么客戶端選項將是:
```
spark.eventLog.enabled true
spark.eventLog.dir hdfs://namenode/shared/spark-logs
```
history server 可以配置如下:
### 環境變量
| 環境變量 | 含義 |
| --- | --- |
| `SPARK_DAEMON_MEMORY` | history server 內存分配(默認值:1g)|
| `SPARK_DAEMON_JAVA_OPTS` | history server JVM 選項(默認值:無)|
| `SPARK_PUBLIC_DNS` | history server 公共地址。如果沒有設置,應用程序歷史記錄的鏈接可能會使用服務器的內部地址,導致鏈接斷開(默認值:無)。 |
| `SPARK_HISTORY_OPTS` | `spark.history.*` history server 配置選項(默認值:無)|
### Spark配置選項
| 屬性名稱 | 默認 | 含義 |
| --- | --- | --- |
| spark.history.provider | `org.apache.spark.deploy.history.FsHistoryProvider` | 執行應用程序歷史后端的類的名稱。目前只有一個實現,由 Spark 提供,它查找存儲在文件系統中的應用程序日志。 |
| spark.history.fs.logDirectory | file:/tmp/spark-events | 為了文件系統的歷史提供者,包含要加載的應用程序事件日志的目錄URL。這可以是 local `file://` 路徑,HDFS `hdfs://namenode/shared/spark-logs` 或者是 Hadoop API 支持的替代文件系統。 |
| spark.history.fs.update.interval | 10s | 文件系統歷史的提供者在日志目錄中檢查新的或更新的日志期間。更短的時間間隔可以更快地檢測新的應用程序,而不必更多服務器負載重新讀取更新的應用程序。一旦更新完成,完成和未完成的應用程序的列表將反映更改。 |
| spark.history.retainedApplications | 50 | 在緩存中保留 UI 數據的應用程序數量。如果超出此上限,則最早的應用程序將從緩存中刪除。如果應用程序不在緩存中,如果從 UI 界面訪問它將不得不從磁盤加載。 |
| spark.history.ui.maxApplications | Int.MaxValue | 在歷史記錄摘要頁面上顯示的應用程序數量。應用程序 UI 仍然可以通過直接訪問其 URL,即使它們不顯示在歷史記錄摘要頁面上。 |
| spark.history.ui.port | 18080 | history server 的Web界面綁定的端口。 |
| spark.history.kerberos.enabled | false | 表明 history server 是否應該使用 kerberos 進行登錄。如果 history server 正在訪問安全的 Hadoop 集群上的 HDFS 文件,則需要這樣做。如果這是真的,它使用配置 `spark.history.kerberos.principal` 和 `spark.history.kerberos.keytab` |
| spark.history.kerberos.principal | (none) | history server 的 Kerberos 主要名稱。 |
| spark.history.kerberos.keytab | (none) | history server 的 kerberos keytab 文件的位置。 |
| spark.history.ui.acls.enable | false | 指定是否應檢查 acls 授權查看應用程序的用戶。如果啟用,則進行訪問控制檢查,無論單個應用程序在運行時為 `spark.ui.acls.enable` 設置了什么。應用程序所有者將始終有權查看自己的應用程序和通過 `spark.ui.view.acls` 指定的任何用戶和通過 `spark.ui.view.acls.groups`,當應用程序運行時也將有權查看該應用程序。如果禁用,則不進行訪問控制檢查。 |
| spark.history.ui.admin.acls | empty | 通過逗號來分隔具有對 history server 中所有 Spark 應用程序的查看訪問權限的用戶/管理員列表。默認情況下只允許在運行時查看應用程序的用戶可以訪問相關的應用程序歷史記錄,配置的用戶/管理員也可以具有訪問權限。在列表中添加 "*" 表示任何用戶都可以擁有管理員的權限。 |
| spark.history.ui.admin.acls.groups | empty | 通過逗號來分隔具有對 history server 中所有 Spark 應用程序的查看訪問權限的組的列表。默認情況下只允許在運行時查看應用程序的組可以訪問相關的應用程序歷史記錄,配置的組也可以具有訪問權限。在列表中放置 "*" 表示任何組都可以擁有管理員權限。 |
| spark.history.fs.cleaner.enabled | false | 指定 History Server 是否應該定期從存儲中清除事件日志。 |
| spark.history.fs.cleaner.interval | 1d | 文件系統 job history 清潔程序多久檢查要刪除的文件。如果文件比 `spark.history.fs.cleaner.maxAge` 更舊,那么它們將被刪除。 |
| spark.history.fs.cleaner.maxAge | 7d | 較早的 Job history 文件將在文件系統歷史清除程序運行時被刪除。 |
| spark.history.fs.numReplayThreads | 25% of available cores | history server 用于處理事件日志的線程數。 |
請注意UI中所有的任務,表格可以通過點擊它們的標題來排序,便于識別慢速任務,數據偏移等。
注意
1. history server 顯示完成的和未完成的 Spark 作業。如果應用程序在失敗后進行多次嘗試,將顯示失敗的嘗試,以及任何持續未完成的嘗試或最終成功的嘗試。
2. 未完成的程序只會間歇性地更新。更新的時間間隔由更改文件的檢查間隔(`spark.history.fs.update.interval`)定義。在較大的集群上,更新間隔可能設置為較大的值。查看正在運行的應用程序的方式實際上是查看自己的 Web UI。
3. 沒有注冊完成就退出的應用程序將被列出為未完成的,即使它們不再運行。如果應用程序崩潰,可能會發生這種情況。
4. 一個用于表示完成 Spark 作業的一種方法是明確地停止Spark Context(`sc.stop()`),或者在 Python 中使用 `with SparkContext() as sc:` 構造處理 Spark 上下文設置并拆除。
## REST API
除了在UI中查看指標之外,還可以使用JSON。這為開發人員提供了一種簡單的方法來為 Spark 創建新的可視化和監控工具。JSON可用于運行的應用程序和 history server。The endpoints are mounted at `/api/v1`。例如,對于 history server,它們通常可以在 `http://<server-url>:18080/api/v1` 訪問,對于正在運行的應用程序,在 `http://localhost:4040/api/v1`。
在 API 中,一個應用程序被其應用程序 ID `[app-id]` 引用。當運行在 YARN 上時,每個應用程序可能會有多次嘗試,但是僅針對群集模式下的應用程序進行嘗試,而不是客戶端模式下的應用程序。YARN 群集模式中的應用程序可以通過它們的 `[attempt-id]` 來識別。在下面列出的 API 中,當以 YARN集群模式運行時,`[app-id]` 實際上是 `[base-app-id]/[attempt-id]`,其中 `[base-app-id]` YARN 應用程序 ID。
| Endpoint | 含義 |
| --- | --- |
| `/applications` | 所有應用程序的列表。<br>`?status=[completed|running]` 列出所選狀態下的應用程序。<br>`?minDate=[date]` 列出最早的開始日期/時間。<br>`?maxDate=[date]` 列出最新開始日期/時間。<br>`?minEndDate=[date]` 列出最早的結束日期/時間。<br>`?maxEndDate=[date]` 列出最新結束日期/時間。<br>`?limit=[limit]` 限制列出的應用程序數量。<br>示例:<br>`?minDate=2015-02-10`<br>`?minDate=2015-02-03T16:42:40.000GMT`<br>`?maxDate=2015-02-11T20:41:30.000GMT`<br>`?minEndDate=2015-02-12`<br>`?minEndDate=2015-02-12T09:15:10.000GMT`<br>`?maxEndDate=2015-02-14T16:30:45.000GMT`<br>`?limit=10` |
| `/applications/[app-id]/jobs` | 給定應用程序的所有 job 的列表。<br>`?status=[running|succeeded|failed|unknown]` 列出在特定狀態下的 job。 |
| `/applications/[app-id]/jobs/[job-id]` | 給定 job 的詳細信息。 |
| `/applications/[app-id]/stages` | 給定應用程序的所有階段的列表。<br>`?status=[active|complete|pending|failed]` 僅列出狀態的階段。 |
| `/applications/[app-id]/stages/[stage-id]` | 給定階段的所有嘗試的列表。 |
| `/applications/[app-id]/stages/[stage-id]/[stage-attempt-id]` | 給定階段的嘗試詳細信息。 |
| `/applications/[app-id]/stages/[stage-id]/[stage-attempt-id]/taskSummary` | 給定階段嘗試中所有任務的匯總指標。<br>`?quantiles` 用給定的分位數總結指標。
Example: `?quantiles=0.01,0.5,0.99` |
| `/applications/[app-id]/stages/[stage-id]/[stage-attempt-id]/taskList` | 給定階段嘗試的所有 task 的列表。<br>`?offset=[offset]&length=[len]` 列出給定范圍內的 task。<br>`?sortBy=[runtime|-runtime]` task 排序.<br>Example: `?offset=10&length=50&sortBy=runtime` |
| `/applications/[app-id]/executors` | 給定應用程序的所有活動 executor 的列表。 |
| `/applications/[app-id]/allexecutors` | 給定應用程序的所有(活動和死亡)executor 的列表。 |
| `/applications/[app-id]/storage/rdd` | 給定應用程序的存儲 RDD 列表。 |
| `/applications/[app-id]/storage/rdd/[rdd-id]` | 給定 RDD 的存儲狀態的詳細信息。 |
| `/applications/[base-app-id]/logs` | 將給定應用程序的所有嘗試的事件日志下載為一個 zip 文件。 |
| `/applications/[base-app-id]/[attempt-id]/logs` | 將特定應用程序嘗試的事件日志下載為一個 zip 文件。 |
| `/applications/[app-id]/streaming/statistics` | streaming context 的統計信息 |
| `/applications/[app-id]/streaming/receivers` | 所有 streaming receivers 的列表。 |
| `/applications/[app-id]/streaming/receivers/[stream-id]` | 給定 receiver 的詳細信息。 |
| `/applications/[app-id]/streaming/batches` | 所有被保留 batch 的列表。 |
| `/applications/[app-id]/streaming/batches/[batch-id]` | 給定 batch 的詳細信息。 |
| `/applications/[app-id]/streaming/batches/[batch-id]/operations` | 給定 batch 的所有輸出操作的列表。 |
| `/applications/[app-id]/streaming/batches/[batch-id]/operations/[outputOp-id]` | 給定操作和給定 batch 的詳細信息。 |
| `/applications/[app-id]/environment` | 給定應用程序環境的詳細信息。 |
可檢索的 job 和 stage 的數量被 standalone Spark UI 的相同保留機制所約束。`"spark.ui.retainedJobs"` 定義觸發 job 垃圾收集的閾值,以及 `spark.ui.retainedStages` 限定 stage。請注意,垃圾回收在 play 時進行:可以通過增加這些值并重新啟動 history server 來檢索更多條目。
### API 版本控制策略
這些 endpoint 已被強力版本化,以便更容易開發應用程序。特別是 Spark 保證:
* endpoint 永遠不會從一個版本中刪除
* 任何給定 endpoint 都不會刪除個別字段
* 可以添加新的 endpoint
* 可以將新字段添加到現有 endpoint
* 將來可能會在單獨的 endpoint 添加新版本的 api(例如:`api/v2`)。新版本 _不_ 需要向后兼容。
* Api 版本可能會被刪除,但只有在至少一個與新的 api 版本共存的次要版本之后才可以刪除。
請注意,即使在檢查正在運行的應用程序的 UI 時,仍然需要 `applications/[app-id]`部分,盡管只有一個應用程序可用。例如:要查看正在運行的應用程序的作業列表,您可以訪問 `http://localhost:4040/api/v1/applications/[app-id]/jobs`。這是為了在兩種模式下保持路徑一致。
# Metrics
Spark 具有基于[Dropwizard Metrics Library](http://metrics.dropwizard.io/)的可配置 metrics 系統。這允許用戶將 Spark metrics 報告給各種接收器,包括 HTTP,JMX 和 CSV 文件。metrics 系統是通過配置文件進行配置的,Spark 配置文件是 Spark 預計出現在 `$SPARK_HOME/conf/metrics.properties`上。可以通過`spark.metrics.conf` [配置屬性](configuration.html#spark-properties)指定自定義文件位置。默認情況下,用于 driver 或 executor metrics 標準的根命名空間是 `spark.app.id` 的值。然而,通常用戶希望能夠跟蹤 driver 和 executors 的應用程序的 metrics,這與應用程序 ID(即:`spark.app.id`)很難相關,因為每次調用應用程序都會發生變化。對于這種用例,可以為使用 `spark.metrics.namespace`配置屬性的 metrics 報告指定自定義命名空間。例如,如果用戶希望將度量命名空間設置為應用程序的名稱,則可以將`spark.metrics.namespace`屬性設置為像 `${spark.app.name}`這樣的值。然后,該值會被 Spark 適當擴展,并用作度量系統的根命名空間。非 driver和 executor 的 metrics 標準永遠不會以 `spark.app.id`為前綴,`spark.metrics.namespace`屬性也不會對這些 metrics 有任何這樣的影響。
Spark 的 metrics 被分解為與 Spark 組件相對應的不同 _instances_。在每個實例中,您可以配置一組報告匯總指標。目前支持以下實例:
* `master`:Spark standalone 的 master 進程。
* `applications`:主機內的一個組件,報告各種應用程序。
* `worker`:Spark standalone 的 worker 進程。
* `executor`:A Spark executor.
* `driver`:Spark driver 進程(創建 SparkContext 的過程)。
* `shuffleService`:The Spark shuffle service.
每個實例可以報告為 0 或更多 _sinks_。Sinks 包含在 `org.apache.spark.metrics.sink`包中:
* `ConsoleSink`:將 metrics 信息記錄到控制臺。
* `CSVSink`:定期將 metrics 數據導出到 CSV 文件。
* `JmxSink`:注冊在 JMX 控制臺中查看的 metrics。
* `MetricsServlet`:在現有的 Spark UI 中添加一個 servlet,以將數據作為 JSON 數據提供。
* `GraphiteSink`:將 metrics 發送到 Graphite 節點。
* `Slf4jSink`:將 metrics 標準作為日志條目發送到 slf4j。
Spark 還支持由于許可限制而不包含在默認構建中的 Ganglia 接收器:
* `GangliaSink`:向 Ganglia 節點或 multicast 組發送 metrics。
要安裝 `GangliaSink`,您需要執行 Spark 的自定義構建。_**請注意,通過嵌入此庫,您將包括 [LGPL](http://www.gnu.org/copyleft/lesser.html)-licensed Spark包中的代碼**_。對于 sbt 用戶,在構建之前設置 `SPARK_GANGLIA_LGPL`環境變量。對于 Maven 用戶,啟用 `-Pspark-ganglia-lgpl` 配置文件。除了修改集群的 Spark 構建用戶,應用程序還需要鏈接到 `spark-ganglia-lgpl` 工件。
metrics 配置文件的語法在示例配置文件 `$SPARK_HOME/conf/metrics.properties.template` 中定義。
# 高級工具
可以使用幾種外部工具來幫助描述 Spark job 的性能:
* 集群范圍的監控工具,例如 [Ganglia](http://ganglia.sourceforge.net/)可以提供對整體集群利用率和資源瓶頸的洞察。例如,Ganglia 儀表板可以快速顯示特定工作負載是否為磁盤綁定,網絡綁定或 CPU 綁定。
* 操作系統分析工具,如 [dstat](http://dag.wieers.com/home-made/dstat/),[iostat](http://linux.die.net/man/1/iostat) 和 [iotop](http://linux.die.net/man/1/iotop) 可以在單個節點上提供細粒度的分析。
* JVM 實用程序,如 `jstack` 提供堆棧跟蹤,`jmap` 用于創建堆轉儲,`jstat` 用于報告時間序列統計數據和 `jconsole` 用于可視化地瀏覽各種 JVM 屬性對于那些合適的 JVM 內部使用是有用的。
- Spark 概述
- 編程指南
- 快速入門
- Spark 編程指南
- 構建在 Spark 之上的模塊
- Spark Streaming 編程指南
- Spark SQL, DataFrames and Datasets Guide
- MLlib
- GraphX Programming Guide
- API 文檔
- 部署指南
- 集群模式概述
- Submitting Applications
- 部署模式
- Spark Standalone Mode
- 在 Mesos 上運行 Spark
- Running Spark on YARN
- 其它
- 更多
- Spark 配置
- Monitoring and Instrumentation
- Tuning Spark
- 作業調度
- Spark 安全
- 硬件配置
- Accessing OpenStack Swift from Spark
- 構建 Spark
- 其它
- 外部資源
- Spark RDD(Resilient Distributed Datasets)論文
- 翻譯進度