Модуль 13. Данные, качество и каталог
В BI/DWH качество данных — это не «раз в квартал запустить проверку». Это часть конвейера и SLO, зашитые в CI/CD и эксплуатацию:
- DQ как код (Great Expectations / Soda / dbt tests / Deequ) → проверки в шагах ETL.
- SLA/SLO на витрины (свежесть, полнота, точность) → алерты по burn-rate (см. Модуль 5).
- Lineage (OpenLineage/Marquez; также DataHub/OpenMetadata) → понять, что сломалось «вверх/вниз по реке».
- Каталог данных → словарь бизнес-терминов, владельцы, политики доступа, качество и метрики — в одном месте.
- Роли: Data Owner ↔ Steward ↔ Инженер платформы — кто за что отвечает в инциденте качества.
DQ: подход и минимум, который должен быть
Принципы
- Shift-left: проверки до публикации витрины («gate»), а не постфактум.
-
Две зоны проверок:
pre-load (схема/доменные ограничения/объём) и post-load (целостность, аномалии, свежесть). - Единый набор стандартных проверок по типам таблиц (факты/измерения/журналы).
- Идемпотентность: повторный прогон DQ не меняет данные.
- Обратимая публикация: если провалились проверки — не выпускаем/откатываем снапшот (Iceberg snapshot rollback/метки).
Минимальный набор проверок (MVP)
- Freshness — лаг обновления витрины ≤ X минут/часов.
- Completeness — обязательные поля not null.
- Uniqueness — ключ уникален (например, order_id в фактах, business_key в измерениях).
- Referential integrity — FK-связи (fct→dim).
- Validity / Domain — значения в допустимых диапазонах/справочниках.
- Row count / Volume — отклонения по количеству строк не выше порога (например, −15%/+30%).
- Distribution drift — базовый тест на дрейф (квантиль/KS на ключевых полях).
- Schema contract — «расширять можно, ломать нельзя»: новые колонки разрешены, удаление/переименование — через RFC.
- PII-скан (по паттернам) — чтобы чувствительное не «утекло» в витрины общего доступа.
- Data type checks — даты, числовые поля, валюты (локаль/часовой пояс → в UTC).
Инструменты
- Great Expectations (GE) — декларативные expectations + отчёт в HTML/JSON; хорошо для pandas/Spark/SQL.
- Soda Core — YAML-чек-файлы, есть интеграции с алертингом.
- dbt tests — простые проверки (unique/not null/relationships) «рядом с моделями».
- Deequ — для Spark-нагрузок на JVM.
Практика: комбинируйте — «широкую сетку» dbt tests, а углублённые проверки и дрейф — в GE/Soda.
SLA/SLO на витрины (и как этим управлять)
Пример формулировок
- Свежесть: 99% времени витрина marts.sales.fct_orders обновлена ≤ 60 мин назад (в 08:00–22:00 пн-пт).
- Полнота: доля строк с not null в обязательных колонках ≥ 99.9%.
- Точность: контроль соотношения «выручка vs платёжная система» — отклонение ≤ 1.5%.
- Доступность: успешные SELECT через Trino ≥ 99.5%.
SLI/алерты
- Метрики freshess/row_count/failed_assertions → в Prometheus (через экспортер/коллектор).
- Алерты двойные: быстрый burn-rate (1 час) и тлеющий (6–12 часов), как в Модуле 5.
Release-gates
- В CD (Модуль 6) есть гейт: если DQ не зелёный или freshness SLI красный, публикация витрины блокируется.
Lineage: что, зачем и каким инструментом
Зачем
- Локализовать последствия: «упал коннектор → какие витрины/дашборды «покрасели»?».
- Ускорить RCA (root cause analysis) и коммуникацию с владельцами.
Инструменты и события
- OpenLineage (стандарт событий: job/run/dataset, column-level lineage). Бэкенд Marquez. Интеграции: Airflow, Spark, dbt, Kafka Connect и т. п.
- Каталоги (DataHub / OpenMetadata) тоже умеют хранить lineage; могут потреблять OpenLineage/вебхуки/интеграции с Airflow/dbt.
Практика
- Включите OpenLineage-провайдер в Airflow → события автоматически улетают в Marquez/каталог.
- В dbt — установите плагин OpenLineage (или нативную интеграцию каталога) → получите lineage вплоть до колонок.
Каталог данных: модель, наполнение, интеграции
Что хранить
- Словарь терминов (бизнес-глоссарий),
- Датасеты (схемы, типы, владельцы, домены, зоны доступа),
- Lineage (входы/выходы),
- Качество (последние проверки/статусы/метрики),
- Политики (чувствительность, PII, RLS),
- Контакты (Owner/Steward).
Как заполнять
- Автосбор: из Airflow/dbt/OpenLineage → lineage, схемы.
- Скрипт-инжест: из S3/Trino/CH/PG тянем схемы и статистику.
- Ручное (минимум): описания бизнес-терминов, владельцы, домены данных.
Интеграции
- Каталоги (DataHub/OpenMetadata/вендорские) имеют эмиттеры/CLI. Их удобно вызывать в шагах Airflow/CI.
- DQ-результаты (GE/Soda) публикуем в каталог как quality assertions/test runs.
Роли и ответственность
|
Роль |
Ответственность |
|---|---|
|
Data Owner (владелец домена) |
SLA/SLO витрин, приоритизация проблем качества, утверждение схем/изменений |
|
Data Steward |
Определение правил качества/терминов, документирование в каталоге, триаж инцидентов DQ |
|
Data Engineer / BI Engineer |
Реализация DQ-чеков, оркестрация в Airflow, интеграции OpenLineage/каталог |
|
Платформенная команда |
Инфраструктура (k8s/Trino/S3), экспортеры метрик, SSO/RBAC, доступы к каталогу |
|
Инфобез/Privacy |
Политики PII/маскировка, аудит доступа, ретенции |
Паттерны внедрения (без лишнего кода)
Где запускать DQ и что блокировать
- Staging слой: тяжёлые проверки (дрейф/статистика) → не бьём по prod витринам.
- Перед публикацией в marts: «жёсткие» проверки (freshness/uniqueness/FK).
- Если «красное» — не публикуем (do not merge snapshot / не рефрешим материализованную витрину).
Как хранить результаты
- В S3/объекте: JSON-лог прогонов, артефакты HTML (GE).
- В каталоге: агрегированный статус/последний прогон/метрики.
- В метриках: gauges dq_assertions_failed, dq_freshness_lag_seconds → Prometheus/Grafana.
Безопасность
- DQ-джобы работают в своих namespace, с read-only доступом к данным.
- Секреты к источникам — через External Secrets (Модуль 4).
- PII-чек → делает семпл/маскирует, не выносит «сырьё» в логи.
Риски и как их снимать
|
Риск |
Проявление |
Митигировать |
|---|---|---|
|
Флакание тестов |
То зелёный, то красный без причин |
Фиксируйте сэмплирование, увеличьте окна агрегации, используйте контрольные ряды |
|
Ложноположительные |
«Шум» в алертах, игнорирование |
Введите «подтверждённые инциденты», пороги на аномалии, burn-rate |
|
Долгие проверки |
ETL окна не укладываются |
Самплинг/approx, heavy-DQ на off-peak, разделите pre/post-load |
|
Несогласованность схемы |
Падает при эволюции колонок |
Contract: «add ok, break via RFC», миграции expand/contract |
|
Дубли инструментов |
GE + dbt + Soda «о том же» |
Матрица ответственности: dbt (базовые), GE/Soda (углублённые) |
|
Нет владельцев |
Каталог пустой, инциденты «висят» |
Назначьте Owner/Steward по доменам; KPI на заполнение каталога |
Мини-фрагменты (ровно сколько нужно)
Airflow: запуск Great Expectations + OpenLineage (идея)
- В переменных окружения Airflow укажите OPENLINEAGE_URL и ключ, чтобы провайдер посылал события.
- GE храните рядом с моделью (репозиторий dq/expectations/...), чекпоинт — как артефакт.
Псевдокод DAG:
1) extract/load staging → 2) run GE checkpoint (pre-publish)
→ 3) if OK → publish marts (snapshot/materialize)
→ 4) emit status to catalog (success/metrics)
→ 5) refresh BI dataset cache
Публикация в каталог (общая схема без привязки к продукту)
-
В задаче Airflow вызываете emitter каталога (CLI/HTTP/SDK) с payload:
- dataset URN (например, urn:trino:iceberg.marts.sales.fct_orders),
- schema (колонки/типы), owner/steward (IDP-группа),
- lineage (upstreams stg_orders, dim_customers),
- assertions (имя проверки, статус, метрика, timestamp).
- Большинство каталогов поддерживают upsert — отправляете факты после каждого прогона.
Практика: «DQ в Airflow + публикация метаданных в каталог»
Цель
Собрать минимально жизнеспособную схему:
- Airflow запускает загрузку stg_orders.
- Запускается GE-checkpoint на stg_orders (not null/unique/доменные значения).
- Если OK — материализуем marts.fct_orders (dbt/Trino).
- Публикуем в каталог: схему датасета, владельца, lineage (stg → fct), результаты DQ.
- В Grafana появляется карточка SLO «freshness/quality», а при провале — алерт.
Шаги (высокоуровнево)
- Каталог/lineage: разверните OpenLineage + Marquez или выбранный каталог (DataHub/OpenMetadata), подключите Airflow к нему.
- Great Expectations: сделайте проект с expectation-suite для stg_orders (минимальный набор из раздела 1.2) и checkpoint.
-
Airflow DAG:
- Task A: загрузка staging;
- Task B: GE-checkpoint (на выход — JSON-результат);
- Task C: «gate» — если B=OK → Task D (публикация fct_orders), иначе → Task E (quarantine/stop);
- Task F: публикация в каталог (owner, schema, lineage, quality run);
- Task G: обновление BI (инвалидировать кэш/датасет).
- Наблюдаемость: коллекция метрик dq_assertions_failed, freshness_lag_seconds, алерты по burn-rate (Модуль 5).
- Документация: в каталоге у fct_orders заполнены бизнес-описание, Owner/Steward, правила качества, RLS/PII тег.
Критерии готовности
- Падение DQ останавливает публикацию fct_orders.
- В каталоге виден lineage (stg_orders → fct_orders) и свежий статус качества.
- В Grafana «зелёный» дашборд SLO для витрины; алерт приходит при превышении порога.
Чек-лист внедрения
- Выбран стандарт DQ и минимум проверок на тип таблицы.
- GE/Soda/dbt tests — в репозитории, запускаются из Airflow (pre/post).
- OpenLineage включён в Airflow/dbt, backend (Marquez/каталог) принимает события.
- Каталог пополняется автоматически (schema/owner/lineage) + ручные термины/описания.
- Freshness/quality SLI собираются в Prometheus, есть burn-rate алерты.
- Release-gates блокируют публикацию «красных» витрин.
- Роли назначены (Owner/Steward/On-call), runbook «инцидент качества» готов.
- PII-контроль и маскировка; DQ-логи без чувствительных данных.
- Регулярный обзор «качества как продукта»: тренды провалов, топ-причины, план улучшений.
Качество данных и каталог — это «операционка», а не «документация». Как только DQ становится шагом пайплайна, lineage — источником правды, а SLO витрин — частью алертинга, инциденты качества перестают быть сюрпризом. Прозрачные владельцы, стандартные проверки и автоматическая публикация метаданных позволяют быстрее чинить поломки и безопасно развивать DWH.




