Какие типовые Spark-задачи ты писал?
Фильтрация, агрегации, join’ы, дедупликация, переработка логики.
Как оптимизировал Spark-задачи?
Broadcast join
Partitioning
Cache / persist
Parquet вместо CSV
Уменьшение shuffle
SQL оптимизации
Был ли опыт падения Spark-задач в проде? Что делал?
1️⃣ Обнаружение проблемы
Обычно я узнавал о падении либо из алёрта Airflow, либо утром при проверке статуса ночных DAG-ов.
Сначала я фиксировал, какой именно DAG и какая Spark-задача упала, и на каком шаге.
2️⃣ Анализ логов
Дальше я открывал логи в Airflow и переходил к логам Spark.
Смотрел stack trace, тип ошибки — OutOfMemory, shuffle failure, проблемы с данными или внешним источником.
Обычно ошибки были:
OOM или превышение executor memory
долгие shuffle и таймауты
некорректные данные
недоступность внешнего API или HDFS
3️⃣ Определение типа проблемы
Я всегда старался понять, это проблема кода, данных или инфраструктуры.
если ошибка в коде или логике трансформаций — брал на себя
если нехватка ресурсов или проблемы с кластером — подключал infra-команду
если проблема в источнике данных — уведомлял команду владельца источника
4️⃣ Временное решение (если критично)
Если пайплайн был бизнес-критичным, я сначала искал быстрый workaround:
ограничить объём данных, изменить фильтр, временно увеличить ресурсы или перезапустить задачу.
5️⃣ Исправление причины
После этого вносил изменения в код:
оптимизировал Spark-задачу
уменьшал количество shuffle
добавлял broadcast join
корректировал партиционирование
усиливал обработку ошибок и ретраи
6️⃣ Тестирование и деплой
Изменения проверялись локально или на тестовом окружении, затем проходили CI/CD.
После деплоя я переобрабатывал данные, если это было необходимо.
7️⃣ Валидация результата
Я проверял, что DAG успешно отработал, данные корректно загрузились, а аналитические витрины не содержат аномалий.
При необходимости сверял результаты с аналитиками.
8️⃣ Пост-инцидентные действия
После инцидента мы:
добавляли дополнительные алёрты
улучшали логирование
дописывали тесты
фиксировали выводы в документации
Цель была — чтобы такая ошибка больше не повторялась.
Какие DAG’и ты делал?
Daily batch ETL, витрины, удаление и архивирование данных
Как обрабатывал ошибки в Airflow?
retries, retry_delay
on_failure_callback
алерты
idempotent задачи
Как проверяешь корректность загрузки данных в Data Lake?
Как анализируешь существующую ETL-логику перед её оптимизацией?
Как оформить pull request и что обязательно должно быть в описании?
Как документируешь свои решения в Confluence, чтобы их могли поддерживать другие команды?
Как тестировались даги, spark-задачи?
> DAG’и и Spark-задачи тестировались через локальный запуск и проверку корректности результатов.
Для Spark использовались unit-тесты на ключевую бизнес-логику трансформаций, что позволяло фиксировать ошибки на раннем этапе.
Также проверялись схемы данных, количество строк и агрегаты на тестовых выборках перед выкаткой в прод.
Как кафка интегрируется со spark?
df = (
spark.readStream
.format("kafka")
.option("kafka.bootstrap.servers", "kafka:9092")
.option("subscribe", "user_events")
.option("startingOffsets", "latest")
.load()
)Что за линтеры в CI/CD?
Это стадия в CI/CD, которая проверяет код на стиль, а также проверка тестов pytest
Почему в первом проекте использовался ClickHouse, а во втором — Greenplum?
В первом проекте ClickHouse использовался для быстрого OLAP и дашбордов, во втором — Greenplum как полноценное аналитическое хранилище с более сложной SQL-логикой и интеграциями.
Для чего был streaming-pipeline во втором проекте?
Streaming-pipeline во втором проекте использовался для обработки пользовательских событий в реальном времени.
Это было нужно, чтобы получать оперативные метрики и быстрее реагировать на происходящие события в системе.
Конкретный набор метрик и бизнес-решений формировался заказчиком, а мы реализовывали требуемую логику обработки и доставки данных.
А почему devops не входил в команду ?
Во втором проекте команда была разделена по ролям: разработчики (Data Engineer) занимались логикой обработки данных и пайплайнами, а деплой и инфраструктурную поддержку выполняла отдельная инфраструктурная команда
А было ли CI/CD во втором проекте?
Полноценного CI/CD в классическом виде во втором проекте не было.
Использовались отдельные элементы: Git, code review, базовые проверки и ручной деплой.
Основной упор был на стабильность пайплайнов и поддержку существующей инфраструктуры.
А можно ли установить условие: выполнение одного дага, если выполнен другой?
Да, можно. В Airflow используют ExternalTaskSensor, чтобы DAG ждал завершения другого DAG, или TriggerDagRunOperator, чтобы один DAG запускал другой после успешного выполнения.
С помощью чего или каким образом архивировались данные?
“Через Airflow DAG запускал Spark-задачи: данные старше TTL читались из HDFS и перекладывались в архивный слой в Parquet, после чего удалялись из основного Data Lake.”
Как проверялись контрольные суммы? Была отдельная колонка?
“Да, использовалась отдельная колонка с контрольной суммой (checksum / hash).
Контрольная сумма вычислялась на стороне источника или на этапе ingestion (например, md5 или sha256 от набора бизнес-полей).
При загрузке в Spark мы пересчитывали хеш и сравнивали его со значением в колонке.
Если контрольная сумма не совпадала, такая запись помечалась как некорректная и откладывалась в отдельный quarantine / error-dataset для последующего анализа.
Основной пайплайн при этом не падал.”
Что значит данные семплировались для проверки корректности загрузки?
“После загрузки мы брали случайную выборку строк и проверяли, что значения полей соответствуют ожидаемым: даты, числовые диапазоны, null-ы.”