天天看點

Prometheus監控spark

Prometheus

『普羅米修斯』,也是希臘之神,取義『先見之明』,應該就是監控的意義所在吧。

它跟 k8s 一樣,也是依據 Google 内部的應用原理設計來的,可以看作是 Google 内部監控系統 Borgmon 的一個實作。

架構圖:

Prometheus監控spark

Prometheus 可以從配置或者用服務發現,去調用各個應用的 metrics 接口,來采集資料,然後存儲在硬碟中,而如果是基礎應用比如資料庫,負載均衡器等,可以在相關的服務中安裝 Exporters 來提供 metrics 接口供 Prometheus 拉取。

采集到的資料有兩個去向,一個是報警,另一個是可視化。

Spark 提供的 webui 已經提供了很多資訊,使用者可以從上面了解到任務的 shuffle,任務運作等資訊,但是運作時 Executor JVM 的狀态對使用者來說是個黑盒,在應用記憶體不足報錯時,初級使用者可能不了解程式究竟是 Driver 還是 Executor 記憶體不足,進而也無法正确的去調整參數。

Spark 的度量系統提供了相關資料,我們需要做的隻是将其采集并展示。

Spark Web

每個SparkContext啟動一個Web UI, 預設接口為4040,用來顯示應用的有用資訊, 包括:

  • scheduler stages 和 tasks清單
  • RDD 大小和記憶體使用率的彙總
  • 環境變量(配置)
  • 運作中的 executor 的資訊

Spark history server

如果開啟了 spark event log ,我們可以通過通路 spark histroy server 看到應用的資訊,包括正在運作和已完成的應用。

Web UI 上隻提供應用的運作的狀态和資訊,但是當應用出現異常和失敗,我們并不能及時知道。也就是說缺失失敗報警的功能。Spark有一個基于 Dropwizard Metrics Library 的可配置的 metrics 系統,允許使用者通過各種方式呈現 metrics, 如 HTTP, JMX 和 CSV 檔案方式。我們可以通過 $SPARK_HOME/conf/metrics.properties 配置或者通過 spark.metrics.conf 指定一個自定義的配置檔案. Spark metrics 根據不同的元件被解耦成不同的執行個體。每個執行個體中都可以可以配置多個 sinks 來接收 metrics。

包括以下執行個體:

  • master: The Spark standalone master process.
  • applications: A component within the master which reports on various applications.
  • worker: A Spark standalone worker process.
  • executor: A Spark executor.
  • driver: The Spark driver process (the process in which your SparkContext is created).
  • shuffleService: The Spark shuffle service.
  • applicationMaster: The Spark ApplicationMaster when running on YARN.

目前 Spark 支援的 sinks 全部在 org.apache.spark.metrics.sink package 裡面,包括:

  • ConsoleSink: 在控制台中顯示 metrics.
  • CSVSink: 以 CSV 檔案的方式定期提供報告.
  • JmxSink: 以 JMX 方式提供.
  • MetricsServlet: 以 servlet 方式在 Spark UI 中提供 JSON 資料.
  • GraphiteSink: 發送給 Graphite 節點.
  • Slf4jSink: 記錄到日志中.
  • StatsdSink: 發送給 Statsd 節點.

我們現在的監控報警系統核心是 Promethues,是以 Spark 的監控報警我們想的方案也是要基于 Prometheus。我們看到 Spark 支援的 sink 裡有 jmx, 順着這個思路我們可以采取 JMXSink + JmxExporter(https://github.com/prometheus/jmx_exporter) 的方式。另外一種思路更直接,我們可以自己開發一個 sink 把 metrics 推到 Prometheus。在調研的過程中發現别人也有使用 Prometheus 監控 Spark 的需求,于是發現了這樣一個包 https://github.com/banzaicloud/spark-metrics,自定義的 Prometheus Sink。

下面介紹一下怎麼使用這樣的 Prometheus Sink 監控 Spark。

Prometheus Sink 配置

因為這裡是利用 Prometheus 的 pushgateway,先把 metrics 推給 pushgateway, 是以配置檔案裡一定要配置 pushgateway 的位址。配置檔案就是我們上面所說的 $SPARK_HOME/conf/metrics.properties 或者 spark.metrics.conf 配置的自定義配置檔案

  • metrics.conf

這裡需要特别注意的一點,預設情況下 dirver 和 executor 的 metrics 使用的命名空間是 application id, 例如 ​

​metrics_application_1584587365518_0205_1_executor_bytesRead_Count​

​, 但因為這個 app id 是随着每個 Spark app 變的,我們往往關心的是所有 app 的 metrics, 是以這裡我們通過配置 sprak.metrics.namespace 來達到目的,可以修改成 app 的名字 ${spark.app.name} 或是一個固定值。

  • jmxCollector 配置

    可以配置收集或不收集哪些對象的名額,這個配置檔案可以靈活選擇目錄。

lowercaseOutputName: false
lowercaseOutputLabelNames: false
whitelistObjectNames: ["*:*"]
blacklistObjectNames: ["java.lang:*", "kafka.consumer:*"]      

依賴

我們知道添加 Spark 的第三方依賴包,我們可以在 spark-submit 通過 –package 指定

例如 

spark-submit --master yarn --package com.banzaicloud:spark-metrics_2.11:2.4-1.0.5 --class Test      

為了全局生效和省去指令行配置我們把相關的依賴都添加到 Spark 的 CLass Path 下, 這裡列出所有需要的依賴包的中央倉庫位址。版本可以換根據自己使用的 Spark 版本調整。

https://repo1.maven.org/maven2/com/banzaicloud/spark-metrics_2.11/2.4-1.0.5/spark-metrics_2.11-2.4-1.0.5.jar
https://repo1.maven.org/maven2/io/prometheus/simpleclient/0.8.1/simpleclient-0.8.1.jar
https://repo1.maven.org/maven2/io/prometheus/simpleclient_dropwizard/0.8.1/simpleclient_dropwizard-0.8.1.jar
https://repo1.maven.org/maven2/io/prometheus/simpleclient_pushgateway/0.8.1/simpleclient_pushgateway-0.8.1.jar
https://repo1.maven.org/maven2/io/prometheus/simpleclient_common/0.8.1/simpleclient_common-0.8.1.jar
https://repo1.maven.org/maven2/io/prometheus/jmx/collector/0.12.0/collector-0.12.0.jar
https://repo1.maven.org/maven2/org/yaml/snakeyaml/1.26/snakeyaml-1.26.jar      

Prometheus 報警配置

當我們完成上述步驟後,我們應該就能在 Promethues pushgateway 中看到 spark 應用的 metrics, 那麼 prometheus 中自然也會收集到 metrics。通過其中的一些名額我們可以監控和告警包括 stage, executor, app 等的執行,如果有失敗我們就你能及時收到告警,進而能快速處理。 

下面是 Prometheus 部分告警規則的示例配置

- name: spark
rules:
- alert: spark executor fail
    expr: "{__name__=~'metrics_application.+applicationMaster_numExecutorsFailed_Value'} > 0"
    for: 1m
    labels:
    severity: critical
    annotations:
    summary: "spark {{ $labels.__name__ }} 大于 0, 達到 {{ $value }}"
    description: "spark executor 有失敗應用"


- alert: spark stage fail
    expr: metrics_zaihui_driver_DAGScheduler_stage_failedStages_Value > 0
    for: 1m
    labels:
    severity: critical
    annotations:
    summary: "spark 應用 {{ $labels.app_name }} failed stage 達到 {{ $value }}"
    description: "spark 應用有 stage 失敗"


- alert: spark app run fail
    expr: delta(metrics_zaihui_driver_LiveListenerBus_listenerProcessingTime_org_apache_spark_HeartbeatReceiver_Count[5m]) == 0
        for: 5m
        labels:
        severity: critical
        group: alert-admin
        annotations:
        summary: "spark 應用 {{ $labels.app_name }} 5min 之内沒有心跳,應用可能已經挂掉"
        description: "spark 應用挂掉,請注意"      

關注公衆号 soft張三豐 

繼續閱讀