Как диагностировать падение Spark-приложения после запуска

«Как диагностировать падение Spark-приложения после запуска» — вопрос из категории Apache Spark, который задают на 33% собеседований Data Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Когда Spark-приложение падает, я действую по чек-листу, начиная с самых частых причин.

1. Анализ логов драйвера (Driver Logs). Первым делом смотрю логи контейнера драйвера (в YARN, K8s или на выделенном сервере). Ищу Exception или Error в конце лога. Частая ошибка — java.lang.OutOfMemoryError: Java heap space.

2. Использование Spark History Server UI. Если приложение упало, его логи доступны в History Server. Я проверяю:

  • Вкладка «Executors»: Были ли исключения на исполнителях (Executor Lost).
  • Вкладка «Stages»: На каком этапе (Stage) произошел сбой. Если задачи (Tasks) постоянно терпят неудачу (Failed) на одном этапе — проблема в данных или логике этого этапа.

3. Проверка конфигурации памяти. Падение часто связано с нехваткой памяти. Я проверяю и при необходимости увеличиваю ключевые параметры, учитывая накладные расходы:

# Пример настройки для spark-submit
spark-submit 
  --executor-memory 8g 
  --driver-memory 4g 
  --conf spark.executor.memoryOverhead=2g   # Важно для off-heap памяти
  --conf spark.driver.maxResultSize=2g 
  my_app.py

4. Отладка проблем с данными. Если падение происходит при чтении данных, я добавляю отладочную печать схемы и проверку на «битые» записи:

val df = spark.read.parquet("hdfs://path/to/data")
println("Schema:")
df.printSchema()

// Чтение с режимом PERMISSIVE для отлова corrupt-записей
val dfSafe = spark.read
  .option("mode", "PERMISSIVE")
  .option("columnNameOfCorruptRecord", "_corrupt_record")
  .parquet("hdfs://path/to/data")

// Поиск записей, которые не удалось распарсить
dfSafe.filter($"_corrupt_record".isNotNull).show(false)

5. Логирование внутри кода. В сложных случаях я добавляю стратегическое логирование до и после трансформаций, чтобы локализовать проблемный участок кода.