
В аналитике больших данных есть старая проблема: код ETL-витрин живет своей жизнью, а документация — своей. Изменяешь логику, забываешь обновить описание колонки — и через месяц никто не помнит, что означает wallet_cards_category_hits.
В Почте Mail (VK) мы решили эту проблему системно, разработав внутренний фреймворк, который делает код витрины и ее документацию неразрывными.
На связи Дима Швеенков. Я все так же руковожу направлением аналитики в команде и отвечаю за данные в Почте Mail, а теперь еще и отвечаю за DWH в VK Tech.
В предыдущих статьях я подробно рассказывал о нашем Data Driven-подходе к работе с данными, а также, в частности, как мы работаем со Spark и какие ключевые проблемы с данными мы решили, чтобы построить свое хранилище данных. Сегодня хотел бы остановиться на более узкой теме — как держать в порядке документацию, если у вас такое же огромное хранилище, как и у нас. Материал короткий, но, надеюсь, будет для вас полезным.
Проблема: ручные зависимости в сложных SQL
Когда SQL-код витрины разрастается до нескольких сотен строк, а количество входных таблиц достигает 15–20, выяснить вручную, от каких датасетов зависит витрина, — нетривиальная задача. Аналитику приходится выискивать все FROM, JOIN, подзапросы и CTE, выписывать их и не пропустить ни одной. Ошибка в зависимостях приводит к тому, что пайплайн запускается до того, как обновились нужные данные, и результат становится некорректным.
В классическом оркестраторе, например Airflow, зависимости приходится прописывать руками. Это долго, скучно, и при каждом изменении SQL-запроса нужно не забыть обновить список Upstream-задач. Наш фреймворк решает эту проблему кардинально: он сам парсит SQL-код, выделяет все таблицы, представления и CTE, строит граф зависимостей и генерирует сенсоры в DAG. Аналитику больше не нужно думать о том, откуда берутся данные: фреймворк сделает это автоматически.
Как это выглядит на практике
Аналитик пишет SQL-файл, но не простой, а с аннотациями прямо в коде. Например:
select dt_event , email , map_from_arrays( collect_list(category), collect_list(category_hits) ) as mail_receive_category_hits -- @Map(UInt8,UInt64) мапка category_id -- maps категорий, содержащая факты получпения писем пользователем
Комментарий -- @Map(UInt8,UInt64) ... — это не просто пояснение. Фреймворк парсит такие аннотации и автоматически генерирует структурированное описание витрины. Рядом лежит meta.yaml, где указываются SLA, параметры партиционирования, расписание, целевая таблица в ClickHouse — и тоже полное описание всех колонок.
Главные преимущества подхода «код как документация»
1. Документация никогда не устаревает
Аннотации живут прямо в коде. Если аналитик меняет тип колонки или ее смысл, он меняет и комментарий. Фреймворк при каждом обновлении витрины перегенерирует документацию. Исчезает класс проблем «код изменили, а описание осталось старое».
2. Автоматические зависимости без боли
Как уже сказано, фреймворк сам анализирует FROM и JOIN в SQL-запросе, строит граф зависимостей и создает сенсоры. Экономит часы на поддержку DAG-файлов.
3. Низкий порог входа для аналитика
Аналитик пишет только SQL и несколько строк в meta.yaml. Ему не нужно разбираться в устройстве Spark-кластера, настройке Airflow или ClickHouse-движках. Все это берет на себя фреймворк.
4. Структурированное описание витрины
В одном месте (SQL + YAML) собрано все: бизнес-логика (SQL), схема данных и типы колонок, SLA, расписание, параметры партиционирования.
5. Автоматическая генерация DAG и бэкфиллы
Фреймворк сам создает задачи на бэкфилл с указанного dt_start до сегодня. Параметр max_active_runs=1 для витрин с лагом — типичный кейс, который не нужно прописывать руками.
6. Документация везде: от README до Data Catalog
На основе meta.yaml и аннотаций фреймворк автоматически генерирует README.md для каждой витрины — с описанием колонок, типами, SLA и ссылками на DAG. Это означает, что в Git-репозитории всегда есть актуальная человекочитаемая документация. Более того, те же метаданные легко экспортируются в корпоративный Data Catalog (например, на основе Apache Atlas или внутреннего решения) или напрямую в Confluence через API. Достаточно запустить задачу экспорта, и все витрины оказываются в едином каталоге данных, где бизнес-пользователи могут искать их по названиям, владельцам и тегам. Документация становится частью инфраструктуры данных.
Чем это отличается от dbt и других?
Подход напоминает dbt (Data Build Tool) — там тоже код + документация + автоматические зависимости. Но есть важные отличия:
Особенность |
dbt |
Наш фреймворк |
Движок |
SQL-трансформации в базе (Snowflake, BigQuery, Redshift) |
Spark + HDFS/S3 + ClickHouse |
Документация |
Отдельные .yml-файлы или встроенные |
Прямые аннотации в SQL-комментариях ( |
Зависимости |
dbt автоматически строит граф по |
Фреймворк парсит любые |
Интеграция с Airflow |
Требуется отдельный оператор ( |
Фреймворк сам генерирует DAG с сенсорами и Spark-задачами |
Типизация колонок |
Через schema.yml |
Прямо в SQL-комментарии, что ближе к коду |
Из других инструментов: Dataform (Google) и Coalesce используют похожие идеи, но они завязаны на конкретные облачные платформы. Наш фреймворк — это внутренняя надстройка над Spark + Airflow, заточенная под инфраструктуру VK.
Итог
Подход «код + аннотации + автоматическая генерация пайплайнов» позволяет аналитикам в Почте Mail выпускать витрины данных за часы, а не дни. Документация становится продуктом разработки, частью кода, а не отдельной задачей. Возможность мигрировать между вычислительными движками без переписывания бизнес-логики делает инфраструктуру данных устойчивой к технологическим изменениям.
Самое главное — простота документации. Чтобы описать колонку, аналитик пишет обычный SQL-комментарий: -- @Type text. Не нужен никакой {{ jinja ref }}, ни {{ doc(...) }}, ни отдельный YAML-файл. Это настолько просто, что запоминается за пару часов и становится естественной привычкой. И от такой маленькой, почти незаметной, детали — колоссальное сокращение времени на написание документации и, что еще важнее, ее поддержку. Разработка и документирование витрины соединяются в один процесс, делая работу аналитика удобной и даже приятной. Код не врет, а комментарий рядом не дает забыть, что здесь происходит.
Это не серебряная пуля, но для больших команд с десятками витрин — один из самых эффективных способов сохранить здравый рассудок и качество данных.