Intro
Apache Spark can process massive volumes of data, but production reliability depends on observing the right signals and acting on them quickly. This guide shows you exactly what to monitor, how to collect and alert on it with low risk, and how to verify the setup. It includes concrete configuration snippets, practical alert rules, expected results, common failure modes, rollback steps, and an operations checklist you can run weekly.
Use this guide to:
- Establish a focused, low-risk pilot before broad rollout.
- Surface driver and executor health, memory pressure, shuffle performance, SQL/Streaming bottlenecks, and integration edges (Kafka, HDFS, Airflow/NiFi triggers).
- Build actionable alerts and dashboards with clear verification steps and recovery actions.
Version and Environment Inventory
Start by writing down exactly what you are running. This avoids incompatible configurations and gives you a clean rollback point.
Record:
- Spark distribution and version (for example: Spark 3.3.x or 3.4.x)
- JVM version (for example: OpenJDK 11 or 17)
- Cluster manager (Standalone, YARN, or Mesos)
- Workload mix (batch, Structured Streaming, Spark SQL)
- Dynamic allocation on/off, typical executor counts and sizes
- Data sources/sinks in scope (for example: Kafka, HDFS, object storage)
- Metrics pipeline components (for example: JMX exporter agent, Prometheus, a dashboard tool)
Baseline expectations:
- Spark exposes metrics via its metrics system and JVM JMX. You will attach a metrics sink or JMX exporter to both driver and executors.
- Logs (driver/executor) are collected centrally (for example: via filebeat/agent or cluster manager logs). You will use specific log patterns for incident triggers and diagnostics.
Safe Configuration Path
Roll out incrementally with a narrow pilot you can inspect locally:
- Choose one non-critical Spark application representing your common workload (for example: a daily ETL with joins and shuffle).
- Instrument driver and executor JVMs with a JMX exporter or enable a known-good Spark metrics sink.
- Collect a minimal metric set: driver JVM memory, executor memory and GC, active tasks, failed tasks, stage duration, shuffle read/write, streaming micro-batch duration (if applicable).
- Build one pilot dashboard and three alerts maximum. Keep alerting narrow and measurable.
- Verify by inducing low-risk test conditions (see Verification) and confirm alerts fire and resolve.
- Document rollback (remove agent flags or metrics sink config) and known-good configs.
- Expand to the next two critical apps after 1-2 weeks of stable signal-to-noise.
This small, measurable pilot is fast to validate and easy to roll back if anything misbehaves.
What To Monitor and Alert On
Spark provides several useful layers of signals. Start with the essentials, then add depth selectively.
Core components and signals
| Component | Metric/Signal | What it tells you | First action |
|---|---|---|---|
| Driver JVM | Heap used %, GC time, thread count | Memory pressure and stalls | Capture heap usage trend, GC logs, right-size driver |
| Executors | Active tasks, task failure rate, executor lost count | Parallelism health and stability | Check node health, logs, and data locality |
| Stages/Jobs | Duration, skew (max vs p50 task time), failure count | Performance hotspots and retries | Inspect skewed partitions and joins |
| Shuffle | Read/write MB, fetch wait time, block transfer errors | Network and disk pressure | Validate shuffle service and disk I/O |
| SQL | Query duration, broadcast size, spill metrics | Plan quality and memory fit | Review plan, adjust broadcast thresholds |
| Streaming | Input rate, processing rate, batch duration, state store size | Backpressure and state growth | Tune trigger, state TTL, and checkpoint health |
| Integrations | Kafka lag, HDFS/FS errors | Upstream/downstream health | Coordinate with platform owners |
Practical alert rules (start small)
Use alerts to surface user-visible issues or urgently developing risks. Begin with a compact set to avoid noise.
| Signal and condition | Rationale | Severity | First action |
|---|---|---|---|
| Driver heap used > 85% for 5m OR GC time > 20% for 5m | Imminent OOM or long pauses | High | Capture metrics, consider memory increase or plan fix |
| Task failure rate > 2% for 10m OR executor lost count increases | Data/node instability | High | Inspect task logs, node health, retry policy |
| Stage p95 task time 3x p50 for 10m | Skew or hotspot | Medium | Check partitioning, skew joins |
| Shuffle fetch wait p95 > 2s for 10m | Network or shuffle service issue | Medium | Validate network, shuffle I/O |
| Streaming batch duration > trigger interval for 3 cycles | Backpressure | High | Reduce work per batch, tune resources |
Notes:
- These are constructed examples and thresholds. Tweak to workload norms after week 1.
- Use rate/ratio metrics where possible to stabilize across varying workload sizes.
Log signals that matter
Supplement metrics with log patterns to accelerate incident triage:
- OutOfMemoryError or GC overhead limit exceeded
- ExecutorLostFailure or FetchFailedException
- TaskKilled due to speculation or preemption spikes
- StateStore maintenance warnings for streaming
- HDFS/Kafka client timeouts and authorization failures
Turn repeated patterns into quiet alerts or runbook links rather than paging immediately.
Implementation: collecting metrics and logs
Spark offers two main approaches to get numeric metrics out of driver and executors: its metrics system (sinks) and JVM JMX. The JMX route is broadly compatible and easy to verify.
Option A: JMX exporter as a Java agent (driver and executors)
- Obtain a JMX exporter jar and choose a port (example: 7071 for driver, 7072 for executors).
- Create a minimal JMX exporter YAML (constructed example):
rules:
- pattern: ".*"
name: jmx_$0
type: GAUGE
labels: {}
- Add the agent to Spark driver and executors. Example spark-submit flags (constructed example paths and ports):
spark-submit \
--class com.example.YourJob \
--conf "spark.driver.extraJavaOptions=-javaagent:/opt/jmx/jmx_exporter.jar=7071:/opt/jmx/jmx.yaml" \
--conf "spark.executor.extraJavaOptions=-javaagent:/opt/jmx/jmx_exporter.jar=7072:/opt/jmx/jmx.yaml" \
--conf "spark.executor.instances=4" \
your-job-assembly.jar
- Verification locally:
- Confirm the driver JMX HTTP endpoint is reachable: curl http://<driver-host>:7071/metrics returns text.
- During a run, confirm at least one executor JMX endpoint responds on its node port.
- Scrape these endpoints into your metrics store and build a pilot dashboard using the signals listed earlier.
Pros: minimal Spark config changes, supports JVM and Spark subsystems via MBeans. Cons: ensure ports are allowed and unique per process.
Option B: Spark metrics system (example sink)
Alternatively, configure Spark's metrics system using spark.metrics.conf to send metrics to a chosen sink (example uses a simple CSV or Graphite-like sink). Constructed example:
Create spark.metrics.conf and place it on classpath or specify via spark.metrics.conf property:
*.sink.csv.class=org.apache.spark.metrics.sink.CsvSink
*.sink.csv.period=10
*.sink.csv.unit=seconds
*.sink.csv.directory=/tmp/spark-metrics
master.source.jvm.class=org.apache.spark.metrics.source.JvmSource
worker.source.jvm.class=org.apache.spark.metrics.source.JvmSource
executor.source.jvm.class=org.apache.spark.metrics.source.JvmSource
driver.source.jvm.class=org.apache.spark.metrics.source.JvmSource
Submit with:
spark-submit \
--conf spark.metrics.conf=/path/to/spark.metrics.conf \
your-job-assembly.jar
Verification:
- Confirm files appear under /tmp/spark-metrics on driver and executor hosts.
- Inspect JVM gauges and task metrics to ensure activity is recorded.
Pros: no extra process ports. Cons: you may need a forwarder to your central metrics store.
Logs
- Ensure driver and executor logs are retained centrally with stable retention.
- Add parsers for common exceptions and Spark subsystem tags (executor ID, stage ID, job ID).
- Index by application ID and attempt number to disambiguate retries.
Dashboards that drive action
Start with one focused dashboard per workload type. Avoid sprawling pages. Group by operator action.
Sections to include:
- Driver health: heap used %, GC time %, threads, JVM CPU.
- Executors: total vs active, lost executors, active tasks, task failures, task time p95.
- Stages and shuffle: stage duration p50/p95, skew (p95/p50), shuffle read/write MBps, fetch wait p95.
- SQL/ETL: input/output records, spill metrics, broadcast size, top-N queries by duration.
- Streaming (if applicable): input vs processing rate, batch duration, backlog/lag, state store size, checkpoint write latency.
- Edges: Kafka lag or HDFS write errors (constructed panels if your metrics include them).
Keep it scannable. Use a max of 12-16 panels on the main view; link to deep dives.
Verification and Diagnostics
Verification ensures you get reliable signals without paging noise. Run these in the pilot before full rollout.
- Endpoint reachability
- Driver: curl the JMX or metrics endpoint and confirm a non-empty response.
- At least one executor: confirm an endpoint during a run.
- If using a sink, validate files or network egress at the expected rate.
- Metric shape and labels
- Confirm application_id, executor_id, stage_id, and job_id appear in metric labels or names.
- Ensure label cardinality is reasonable (for example: do not expose per-partition labels).
- Alert dry-runs (constructed examples)
- Memory risk: allocate a larger dataset to push driver heap used > 85% temporarily; verify alert fires and resolves when load ends.
- Task failures: introduce a controlled bad input row set to cause a small number of failures; confirm rate-based alert triggers without spamming.
- Shuffle pressure: run a wide join to raise shuffle read/write; watch fetch wait distribution.
- Streaming backpressure: reduce resources for one test run to make batch duration exceed trigger interval; verify alert.
- Cross-checks
- Compare dashboard trends with Spark UI for the same application attempt.
- Confirm that stage durations and task counts match within reasonable bounds.
- Runbook rehearsal
- For each alert, follow your first action steps and confirm they are sufficient. Update runbook notes with hostnames, file paths, and commands you actually used.
Expected results:
- Metrics arrive within 10-30 seconds of change.
- Alerts fire within one evaluation window, resolve when the condition clears, and do not flap.
- Operators can correlate alert to Spark UI and logs in under 2 minutes.
Failure Modes and Recovery
Anticipate and prepare for these common issues.
- Exporter not attached or wrong port
- Symptom: no metrics from driver/executors; scrape errors.
- Fix: confirm extraJavaOptions flags, jar path, and port availability. Restart the job.
- Rollback: remove extraJavaOptions and redeploy the job.
- High-cardinality labels
- Symptom: metrics store bloat, slow dashboards.
- Fix: relabel to remove per-task or per-partition labels; aggregate at stage/job/app level.
- Rollback: revert to previous mapping or rules file.
- Dynamic allocation churn
- Symptom: rapidly appearing/disappearing executors cause missing time series or noisy alerts.
- Fix: aggregate alerts at application level; add minimum allocation to stabilize metrics during pilot.
- Rollback: disable the relevant alerts until stable.
- Log shipping gaps
- Symptom: missing driver/executor logs during incidents.
- Fix: verify agent permissions and rotation settings; increase retention during rollout.
- Rollback: fall back to cluster manager logs while agents are repaired.
- Network or firewall blocks
- Symptom: scraper cannot reach JMX ports.
- Fix: open the required ports from the scraper to driver/executor nodes; consider using node-level exporters.
- Rollback: switch to Spark metrics sink approach that uses existing egress paths.
- Alert fatigue
- Symptom: too many Medium pages, operators ignore.
- Fix: demote non-urgent to ticket or email; tighten conditions and durations.
- Rollback: revert to the smaller starter set of alerts.
Recovery checklist after a monitoring change:
- If new config caused instability, immediately redeploy the last known-good job configuration.
- Confirm previous metrics and alerts function as before.
- Open a change record noting timestamps, configs, and rollback reason.
Practical runbook actions
When an alert fires, operators need concrete next steps.
Driver memory pressure:
- Capture current heap, GC time %, and recent query/stage workloads.
- Check Spark UI storage tab for cached datasets; evict if safe.
- Consider increasing driver memory for the next run or refactoring large collect() calls.
Task failures or executor loss:
- Inspect executor logs for disk, network, or OOM errors.
- Validate input data consistency for that run window.
- If a small subset of partitions fail, re-run the stage with retries after fixing input.
Shuffle bottlenecks:
- Check shuffle service health and disk I/O on affected nodes.
- Consider increasing shuffle partitions or enabling adaptive query execution for better partition sizing.
Streaming backpressure:
- Compare input rate to processing rate; adjust trigger interval.
- Tune state store compaction or TTL; ensure checkpoint storage is healthy and low latency.
Operations Checklist
Use this checklist weekly and during rollouts.
- Inventory
- Verify Spark, JVM, and metrics tool versions are unchanged or documented.
- Confirm driver and executor agent flags or sink configs in version control.
- Smoke checks
- Run a small job and confirm metrics and logs arrive within 30s.
- Verify at least one executor metrics endpoint is reachable during execution.
- Dashboards
- Confirm driver, executor, stage, and shuffle panels display current data.
- Review top-N slow jobs or queries by duration.
- Alerts
- Review past week alerts; adjust thresholds/durations to reduce noise.
- Manually trigger one safe test alert per month (for example: short, controlled load spike).
- Capacity signals
- Check driver heap trends and GC time over the last 7 days.
- Review executor failure counts and reasons.
- Data edges
- Inspect Kafka lag or HDFS errors panel for anomalies.
- Runbooks
- Update steps with any new file paths, ports, or tool changes.
- Ensure on-call rotation has access and permissions.
- Backup and rollback
- Store current configs and last known-good versions.
- Confirm you can remove agent flags and redeploy within 10 minutes.
Conclusion
You now have a practical, low-risk path to implement Apache Spark monitoring and alerting:
- Start with a narrow pilot and a small, high-value metric set.
- Attach a JMX exporter or configure Spark metrics sinks for driver and executors.
- Build one focused dashboard and a compact, actionable alert set.
- Verify endpoints, metric labels, and alert behavior with safe tests before extending cluster-wide.
- Anticipate failure modes and keep rollback steps ready.
Once the pilot runs reliably for 1-2 weeks, roll out to more applications, tuning thresholds by workload. Keep changes small, measurable, and easy to inspect locally before broad deployment. This disciplined approach reduces rework and leads to faster, more confident incident response.