天天看点

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张三丰 

继续阅读