Data contracts на собеседовании Data Engineer

Проверь себя · 1/3разбор после ответа
У вас есть таблицы users(email) и marketing_signups(email). В одной системе email сохраняется как Ivan@Example.com, в другой — ivan@example.com. Какой подход в JOIN чаще всего решает проблему без изменения данных в таблицах?

Зачем разбирать на собесе

Data contract (контракт данных) — это формальное соглашение между тем, кто данные производит (producer), и теми, кто их потребляет (consumers). Оно фиксирует, как устроен датасет: какие колонки, какие типы, какие гарантии по свежести и качеству, кто за это отвечает и как будут меняться правила. По сути это тот же API-контракт, только для данных, а не для сервиса.

Тему подняли, потому что она решает боль, знакомую любому DE: аналитик выкатил дашборд, продюсер молча переименовал колонку — и наутро всё красное. Классический data lake без контрактов превращается в «свалку», где никто не знает, можно ли доверять таблице. Контракты переносят проверку качества влево, ближе к источнику: ломающее изменение ловится на pull request продюсера, а не в проде у потребителя.

На собесе DE это почти всегда вопрос про архитектуру и процесс, а не про синтаксис: «как ты координируешь изменения между продюсерами и потребителями данных», «как не дать сломать даунстрим при изменении схемы», «кто отвечает за качество витрины». Интервьюер смотрит, понимаете ли вы, что за пределами кода пайплайна есть организационная проблема — договориться, кто что гарантирует, — и что контракт её формализует.

Что включает контракт

Контракт — это не только список колонок. Полноценное соглашение обычно описывает шесть блоков.

  • Схема (schema). Колонки, их типы и ограничения: что nullable, что уникально, какие допустимые диапазоны значений. Это ядро контракта — то, на что потребитель может опереться, строя запросы.
  • SLA по качеству. Измеримые гарантии: свежесть (freshness — данные обновляются не реже раза в час), полнота (completeness — не больше 0.1% пропусков в ключевом поле), точность и уникальность. Не «данные хорошие», а конкретные пороги, которые можно проверить автоматически.
  • Ответственность (ownership). Кто владелец-продюсер и кто отвечает (accountable), если контракт нарушен. Без явного владельца контракт мёртв: некому чинить и не с кого спросить.
  • Версионирование. Текущая версия и история изменений. Потребитель должен понимать, на какую версию он подписан и что поменялось между версиями.
  • Политика ломающих изменений (breaking change policy). Что считается ломающим изменением, за сколько дней предупреждают и как выводят из эксплуатации старые поля (deprecation). Обычно удаление или переименование колонки, сужение типа, добавление обязательного поля без значения по умолчанию — ломают потребителя; добавление опционального поля — нет.
  • Флаги соответствия (compliance). Есть ли в датасете персональные данные (PII), какие регуляторные ограничения. Важно для доступов и хранения.

Формат

Контракт хранят как код: YAML-файл в git, который ревьюят обычным pull request. Это даёт версионирование из коробки, историю изменений и возможность повесить проверки в CI.

name: orders
owner: orders-team          # владелец-продюсер
version: 1.2

schema:
  - name: order_id
    type: bigint
    nullable: false
    unique: true
  - name: amount
    type: decimal(10,2)
    nullable: false
    range: [0, 1000000]     # допустимый диапазон значений
  - name: created_at
    type: timestamp
    nullable: false

sla:
  freshness: 1 hour          # данные обновляются не реже раза в час
  completeness: 99.9%        # не больше 0.1% пропусков
  uniqueness: 100%

compliance:
  contains_pii: false        # персональных данных нет

deprecation:
  notice_period: 90 days     # за сколько предупреждают об удалении поля

Держать контракт «как код» — сознательный выбор: изменение схемы проходит через ревью, как обычный код, и его видно в истории. Это и есть та самая сдвижка проверки влево, к источнику.

Как контракт проверяется

Написать контракт мало — его нужно принудительно применять (enforcement), иначе это просто документация, которая быстро расходится с реальностью. Есть три уровня проверки.

  • Проверки в CI. Когда продюсер меняет схему, пайплайн CI сравнивает новую версию со старой и падает, если изменение ломающее. Так ломающее изменение ловится до мержа, а не в проде.
  • Мониторинг в рантайме. Проверяем, что реальные данные соответствуют контракту: свежесть, пропуски, диапазоны, уникальность. Здесь работают инструменты вроде Great Expectations или Soda, которые прогоняют набор проверок по свежей партиции.
  • Алерты. Нарушение SLA (данные протухли, выросли пропуски) шлёт уведомление владельцу. Ключевой момент — алерт летит продюсеру, который может починить, а не молча ломает даунстрим.

Для стриминга через Kafka роль рантайм-проверки схемы играет Schema Registry (Confluent или альтернативы): продюсер не может отправить сообщение, несовместимое с зарегистрированной схемой, а совместимость эволюции (backward/forward) проверяется на лету.

Готовишься к собесу Data Engineer?
Spark, Airflow, ClickHouse, SQL для DE — вопросы с разборами в Telegram
Тренировать DE в Telegram

Инструменты

  • Soda / Soda Contracts. YAML-описание проверок, дружелюбное к CI. Заточено именно под контракты и SLA качества.
  • Great Expectations. Наборы «ожиданий» (expectation suites) как контракты: богатая библиотека проверок и автогенерация документации о качестве.
  • dbt tests. Самый простой вход: тесты на уникальность, not null, принятые значения и связи прямо в определении моделей. Не полноценный контракт, но покрывает базу схемы и качества.
  • OpenLineage. Про происхождение данных (lineage): помогает понять, кого сломает изменение схемы, ещё до того как оно уедет.
  • Apache Iceberg. Табличный формат с безопасной эволюцией схемы: добавление, удаление и переименование колонок с гарантиями совместимости на уровне хранилища.

В РФ чаще всего это не отдельный «продукт для контрактов», а комбинация: dbt tests плюс Great Expectations или Soda, кастомные проверки в CI и договорённости команд. Полноценные платформы контрактов встречаются реже, чем в докладах на конференциях.

Частые ошибки

  • Путать контракт с тестами качества. dbt-тесты проверяют данные, но контракт — это ещё и соглашение: владелец, SLA, политика изменений, срок предупреждения. Тесты без договорённости об ответственности контрактом не делают.
  • Контракт без enforcement. YAML, который никто не проверяет ни в CI, ни в рантайме, за месяц расходится с реальностью и вводит в заблуждение сильнее, чем его отсутствие.
  • Нет владельца. Если не написано, кто чинит при нарушении, алерт уходит в пустоту. Ownership — не формальность, а самое важное поле.
  • Считать любое изменение схемы ломающим. Добавление опционального поля со значением по умолчанию обычно безопасно. Ломают удаление, переименование, сужение типа и добавление обязательного поля без default.
  • Забыть про PII и доступы. Флаги compliance влияют на то, кому и как можно давать данные. Пропустить их — риск не технический, а юридический.

Связанные темы

FAQ

Чем data contract отличается от обычных тестов качества?

Тесты (например, dbt tests) проверяют, что данные соответствуют ожиданиям. Контракт шире: это соглашение между продюсером и потребителями, где кроме схемы зафиксированы SLA, владелец, версия и политика изменений. Тесты — часть механизма enforcement, но не весь контракт.

Что считается ломающим изменением (breaking change)?

Обычно — удаление или переименование колонки, сужение типа (например, bigint → int), добавление обязательного поля без значения по умолчанию, ужесточение ограничений. Не ломают: добавление опционального поля с default, расширение типа, ослабление ограничений. Именно ломающие изменения ловят в CI.

Как контракт применяется на практике?

Три уровня: проверки в CI при изменении схемы продюсером, мониторинг соответствия реальных данных контракту в рантайме (Great Expectations / Soda), алерты владельцу при нарушении SLA. Для Kafka схему на лету проверяет Schema Registry.

Кто отвечает за data contract?

Владелец-продюсер, который данные производит. Он гарантирует схему и SLA и чинит нарушения. Поэтому поле ownership — обязательное: без явного владельца контракт не работает.

Это официальная информация о вакансиях?

Нет. Статья основана на публичных источниках, документации Soda и Great Expectations и материалах сообщества data contracts. Конкретные требования зависят от компании и команды.


Тренируйте Data Engineering — откройте тренажёр с 1500+ вопросами для собесов.