Система метрик и Prometheus
Spark UI и History Server показывают метрики по запросу — вы открываете страницу и видите текущее состояние. Но для production вам нужен continuous monitoring: сбор метрик каждые 15 секунд, хранение истории, алерты при аномалиях. Для этого Spark интегрируется с Prometheus — стандартом мониторинга в мире distributed systems.
Архитектура метрик Spark
Система метрик Spark построена на модели Sources + Sinks:
Sources — компоненты Spark, которые генерируют метрики. Каждый Source обновляет счётчики (counters), gauges и timers в реальном времени.
Sinks — способы экспорта метрик. Для Prometheus используется встроенный PrometheusServlet — HTTP endpoint, который Prometheus периодически scrape’ит.
PrometheusServlet: встроенный экспортёр
Начиная со Spark 3.0, в Spark встроен PrometheusServlet — HTTP sink, который экспонирует метрики в формате Prometheus на endpoint /metrics/prometheus. Не нужны внешние JAR-файлы или Pushgateway.
Конфигурация: metrics.properties
Создайте файл metrics.properties в директории $SPARK_HOME/conf/:
# Включить PrometheusServlet для всех компонентов
*.sink.prometheusServlet.class=org.apache.spark.metrics.sink.PrometheusServlet
*.sink.prometheusServlet.path=/metrics/prometheus
# Включить JVM метрики для всех компонентов
master.source.jvm.class=org.apache.spark.metrics.source.JvmSource
worker.source.jvm.class=org.apache.spark.metrics.source.JvmSource
driver.source.jvm.class=org.apache.spark.metrics.source.JvmSource
executor.source.jvm.class=org.apache.spark.metrics.source.JvmSource
После настройки метрики доступны по HTTP:
# Master metrics
curl http://spark-master:8080/metrics/prometheus/
# Worker metrics
curl http://spark-worker:8081/metrics/prometheus/
# Driver metrics (только при активном приложении)
curl http://spark-driver:4040/metrics/prometheus/
Анти-паттерн: использование Pushgateway для Spark метрик
До Spark 3.0 для интеграции с Prometheus требовался внешний Prometheus Sink JAR + Pushgateway. Сейчас PrometheusServlet встроен — используйте его. Pushgateway добавляет лишнюю сложность и точку отказа.
Ключевые метрики Spark
JVM Metrics
| Метрика | Что показывает | Когда бить тревогу |
|---|---|---|
jvm_heap_used | Использование heap memory | > 80% от max |
jvm_heap_max | Максимальный размер heap | Слишком маленький для workload |
jvm_non_heap_used | Non-heap memory (metaspace) | Растёт без остановки |
jvm_gc_time_total | Суммарное время GC | > 10% от uptime |
jvm_gc_count_total | Количество GC циклов | Частые Full GC |
Executor Metrics
| Метрика | Что показывает | Когда бить тревогу |
|---|---|---|
executor_cpuTime_total | CPU время executors | Низкое CPU = ожидание I/O |
executor_runTime_total | Время выполнения tasks | Сравните с cpuTime |
executor_memoryUsed | Использование памяти | Близко к лимиту |
executor_diskBytesSpilled | Spill на диск | > 0 = нужно больше памяти |
executor_totalShuffleRead | Shuffle read bytes | Слишком много = плохой partitioning |
executor_totalShuffleWrite | Shuffle write bytes | >> read = data explosion |
DAG Scheduler Metrics
| Метрика | Что показывает | Когда бить тревогу |
|---|---|---|
DAGScheduler_job_activeJobs | Активные jobs | Слишком много параллельных jobs |
DAGScheduler_stage_failedStages | Упавшие stages | > 0 в production |
DAGScheduler_stage_runningStages | Выполняющиеся stages | Застревают надолго |
Prometheus Scrape Configuration
Prometheus нужно настроить для scraping всех компонентов Spark-кластера:
# prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'spark-master'
metrics_path: '/metrics/prometheus/'
static_configs:
- targets: ['spark-master:8080']
labels:
component: 'master'
- job_name: 'spark-workers'
metrics_path: '/metrics/prometheus/'
static_configs:
- targets: ['spark-worker-1:8081', 'spark-worker-2:8081']
labels:
component: 'worker'
- job_name: 'spark-driver'
metrics_path: '/metrics/prometheus/'
scrape_timeout: 10s
static_configs:
- targets: ['spark-driver:4040']
labels:
component: 'driver'
Важные нюансы:
- Driver endpoint (
port 4040) доступен только при активном приложении. Когда job завершается, endpoint исчезает. Установитеscrape_timeout: 10sчтобы Prometheus не ждал слишком долго - Workers слушают на порту 8081 по умолчанию. Если у вас несколько workers на одной машине, порты будут 8081, 8082, 8083…
- Labels (
component: master/worker/driver) помогают фильтровать метрики в Grafana
Попробуйте сами: Docker Lab
Мы подготовили Docker lab с готовым Spark + Prometheus + Grafana стеком. В нём вы сможете:
- Запустить Spark-кластер с настроенным PrometheusServlet
- Отправить workload и наблюдать метрики в реальном времени
- Исследовать Prometheus targets и PromQL запросы
- Увидеть, как метрики отражают проблемы (spill, skew, GC pressure)
Подробности в файле labs/monitoring/README.md и в уроке по Grafana dashboards.
Multi-node Production Setup
В production с десятками workers ручное перечисление targets непрактично. Используйте service discovery:
# prometheus.yml для Kubernetes
scrape_configs:
- job_name: 'spark-executors'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_spark_role]
action: keep
regex: executor
Для Standalone кластера — используйте file-based service discovery:
scrape_configs:
- job_name: 'spark-workers'
file_sd_configs:
- files:
- '/etc/prometheus/spark-targets.json'
refresh_interval: 30s
Что дальше?
Prometheus собирает и хранит метрики, но для визуализации и алертинга нужен Grafana. В следующем уроке мы построим Grafana dashboard с панелями для каждой ключевой метрики Spark.