Архитектура и эволюция платформы данных: Lambda, Kappa, lakehouse, Data Mesh и миграции
Вопрос «какой стек выбрать для данных» задают чаще всего и отвечают на него хуже всего — потому что он поставлен неправильно. Стек не выбирается из списка модного; он выводится из четырёх чисел (объём, требуемая свежесть, число потребителей, размер команды) и одного ограничения (регуляторного). Одна и та же компания за пять лет проходит три разные архитектуры, и каждая из них была правильной в свой момент — а главной ошибкой обычно оказывается не «выбрали не то», а «выбрали архитектуру на вырост, которую некому эксплуатировать».
Эта статья закрывает трек: мы поднимаемся с уровня отдельных механизмов на уровень системы целиком — как она устроена, как меняется с ростом компании и как её переносить, не потеряв доверие к числам.
1. Три архитектурных семейства
Lambda. Два пути: пакетный (медленный, точный) и скоростной (быстрый, приблизительный), а потребитель видит объединение. Решает реальную проблему — «нужно и быстро, и точно», — но платит самой дорогой валютой: одна и та же бизнес-логика написана дважды, на разных движках, и расходится она не «если», а «когда». Сегодня Lambda оправдана редко: когда точный пересчёт технически невозможен в потоке (сложные оконные функции по всей истории) и при этом нужны секунды задержки.
Kappa. Всё — поток; пакетная обработка это просто чтение потока с начала. Красиво и логично, дорого в эксплуатации: состояние, чекпоинты, реплей, эволюция схемы состояния. Оправдана там, где поток и есть суть бизнеса: антифрод, биржа, телеметрия, реальные операции в реальном времени. Механика подробно разобрана в «Потоковой обработке».
ELT поверх lakehouse или облачного хранилища — то, чем в 2026 году является 80 % платформ. Данные приземляются как есть, трансформации живут в SQL, слои разделены (raw → staging → core → marts), таблицы лежат в открытом формате с ACID. Потоковая часть добавляется точечно — там, где задержка в час действительно неприемлема, а не «хотелось бы».
| Семейство | Что решает | Чем платите | Когда разумно |
|---|---|---|---|
| Пакетный ELT / lakehouse | простота, стоимость, понятность | задержка от минут до часов | почти всегда как основа |
| Плюс точечный стриминг | секунды там, где нужно | вторая среда исполнения | 1–5 сценариев из сотни |
| Lambda | и быстро, и точно | двойная реализация логики | точность недостижима в потоке |
| Kappa | единая модель вычислений | сложность состояния и реплея | поток — суть продукта |
Практическое правило: свежесть — самый дорогой параметр платформы. Переход от суток к часу стоит условно вдвое, от часа к минуте — ещё вчетверо, от минуты к секунде — на порядок. Поэтому вопрос «какая задержка нужна» задаётся не архитектору, а тому, кто принимает решение по данным, и ответ должен быть обоснован решением, а не ощущением.
2. Что на самом деле определяет выбор
+ dbt + cron] B -->|"1–50 ТБ"| D{Нужна ли задержка
меньше 15 минут?} B -->|"больше 50 ТБ"| E{Своя инфраструктура
обязательна?} D -->|нет| F[Облачное хранилище
+ ELT + оркестратор] D -->|да| G[То же + точечный стриминг
для 1–3 сценариев] E -->|нет| H[Lakehouse на объектном хранилище
+ открытый табличный формат] E -->|да| I[Свой кластер: ClickHouse / Trino
+ Iceberg на своём S3] C --> J{Больше 3 команд-потребителей?} F --> J G --> J H --> J I --> J J -->|нет| K[Централизованная команда данных] J -->|да| L[Общая платформа
+ доменное владение витринами]
Шесть факторов, в порядке влияния на решение:
- Объём активных данных — не «сколько всего накоплено», а «сколько читается регулярно». Разница часто в двадцать раз.
- Требуемая свежесть — самый дорогой параметр, см. выше.
- Число и разнородность потребителей — 5 аналитиков и 40 команд требуют разных моделей владения.
- Число источников — 8 источников делает один человек, 80 требуют слоя приёма как продукта (см. главу 09).
- Размер и опыт команды — архитектура, которую некому эксплуатировать, хуже более простой. Kafka + Flink + Iceberg в команде из двух человек — это не платформа, а способ не спать.
- Регуляторные ограничения — резидентность, доступ, аудит, право на удаление; иногда именно они вычёркивают половину вариантов ещё до технического обсуждения.
3. Стадии зрелости
Платформа не проектируется один раз — она проходит стадии, и на каждой болит своё.
| Стадия | Команда | Типичный стек | Что болит | Характерный провал |
|---|---|---|---|---|
| 0. Отчёты из реплики | 0–1 инженер | реплика продовой БД, SQL, таблицы | продакшн ложится от тяжёлых запросов | «сделаем отдельную БД потом» |
| 1. Первое хранилище | 1–3 | облачное хранилище, dbt, cron/Airflow, BI | нет тестов и владельцев, всё держится на одном человеке | автобусный фактор равен единице |
| 2. Платформа | 4–10 | + слои, CI, каталог, качество, стриминг точечно | очередь задач от бизнеса растёт быстрее команды | команда данных становится бутылочным горлышком |
| 3. Самообслуживание | 10–30 | + контракты, шаблоны, доступ по ролям, атрибуция стоимости | согласованность определений между доменами | «каждый считает выручку по-своему» |
| 4. Федерация | 30+ | + доменное владение, общий каталог, стандарты | стоимость координации, дублирование витрин | mesh без платформы = хаос с новым названием |
Два наблюдения из практики. Первое: стадии нельзя перепрыгивать. Попытка построить стадию 4 в компании из десяти человек даёт всю сложность федерации без единого её преимущества. Второе: переход между стадиями всегда болезненнее, чем кажется, потому что меняется не стек, а модель владения — кто отвечает за корректность чисел.
4. Централизованная команда или Data Mesh
Централизованная команда данных отлично работает до тех пор, пока успевает. Дальше начинается знакомое: очередь задач на квартал вперёд, инженер, который переспрашивает у бизнеса смысл поля, дашборды, которые «почти правильные». Ответ, предложенный Жамак Дегани в Data Mesh, устроен на четырёх принципах: доменное владение данными, данные как продукт, платформа самообслуживания и федеративное вычислимое управление.
Где mesh ломается на практике — три места, и все три предсказуемы:
- Нет платформы самообслуживания. Третий принцип пропускают чаще всего: доменам отдают ответственность, но не дают инструментов. Результат — сорок команд, каждая со своим Airflow, своими соглашениями и своей «выручкой».
- Нет вычислимого управления. «Федеративное управление» без автоматических проверок в CI — это комитет. Правило, которое нельзя нарушить и получить красную сборку, правилом не является (см. governance).
- Домены не имеют людей. Владение данными требует инженерных навыков внутри домена. Если их нет, ответственность формально переехала, а фактически осталась.
Работающий на практике компромисс — hub-and-spoke: центральная команда владеет платформой, приёмом, ядром модели и стандартами; доменные команды владеют своими витринами и определениями своих метрик. Границы владения удобно проводить по ограниченным контекстам — этот язык подробно разобран в «Ограниченных контекстах», и половина споров о том, «чья это метрика», на самом деле является спором о границах контекста.
5. Build vs buy
Считать нужно не цену лицензии, а совокупную стоимость владения на три года: лицензия + инфраструктура
- время инженеров на эксплуатацию + стоимость простоя + стоимость выхода.
| Компонент | По умолчанию | Строить самому, если |
|---|---|---|
| Коннекторы к SaaS | купить | источник уникален или критичен для денег |
| CDC из своих баз | открытое решение (Debezium) | экзотическая СУБД или жёсткие требования к задержке |
| Хранилище | купить (облако) | регуляторика запрещает облако; объёмы делают своё дешевле |
| Оркестратор | открытое решение | никогда не строить свой; это ловушка, из которой не выходят |
| Трансформации | открытое решение (dbt/SQLMesh) | почти никогда |
| Каталог и линидж | купить или открытое | если нужен глубокий колоночный линидж под свой диалект |
| Качество данных | открытое + свои проверки | свои проверки всегда, фреймворк — редко |
| BI | купить | никогда |
| Сервинг | зависит от продукта | часто своё, потому что это часть продукта |
Про lock-in полезно думать не как про идеологию, а как про стоимость выхода. Она резко падает, если данные лежат в открытом формате (Parquet + Iceberg/Delta), логика написана на переносимом SQL, а оркестрация не завязана на проприетарные примитивы. Тогда смена движка — проект на кварталы, а не переписывание платформы с нуля. Наоборот, витрины, живущие только внутри проприетарного хранилища с диалектными функциями, делают миграцию проектом на годы — и именно поэтому её никогда не начинают.
Отдельно стоит сказать про самое дорогое «строить»: собственный оркестратор. Он всегда начинается как «маленький планировщик на 200 строк» и всегда заканчивается тремя человеко-годами на ретраи, backfill, зависимости, UI и наблюдаемость — то есть на повторение того, что уже сделано в Airflow, Dagster и Prefect (см. главу 05).
6. Миграция платформы
Рано или поздно приходится переезжать: из Redshift в Snowflake, из Hive в Iceberg, из самописного планировщика в Airflow, из одного облака в другое. Ключевое свойство таких проектов — асимметрия: техническая часть занимает 30 % времени, миграция потребителей — 70 %.
Практика, без которой миграция данных проваливается:
- Параллельный запуск с ежедневной сверкой. Обе платформы считают одно и то же, отчёт сравнивает ключевые меры по дням. Допуск объявлен заранее и записан: для денег — ноль, для событийных метрик — доли процента. Расхождение разбирается до причины, а не списывается на «округление».
-- Отчёт параллельного запуска. Считается каждое утро и рассылается автоматически;
-- пока в нём есть строки, переключать потребителей нельзя.
WITH old_side AS (
SELECT business_date, region, SUM(revenue) AS revenue, COUNT(*) AS rows_cnt
FROM legacy.mart_sales
WHERE business_date >= CURRENT_DATE - 60
GROUP BY 1, 2
),
new_side AS (
SELECT business_date, region, SUM(revenue) AS revenue, COUNT(*) AS rows_cnt
FROM analytics.mart_sales
WHERE business_date >= CURRENT_DATE - 60
GROUP BY 1, 2
)
SELECT COALESCE(o.business_date, n.business_date) AS business_date,
COALESCE(o.region, n.region) AS region,
o.revenue AS old_revenue,
n.revenue AS new_revenue,
n.revenue - o.revenue AS delta,
ROUND(100.0 * (n.revenue - o.revenue) / NULLIF(o.revenue, 0), 4) AS delta_pct,
n.rows_cnt - o.rows_cnt AS rows_delta
FROM old_side o
FULL OUTER JOIN new_side n
ON o.business_date = n.business_date AND o.region = n.region
-- Допуск объявлен заранее: для денег он нулевой, поэтому здесь IS DISTINCT FROM,
-- а не сравнение с эпсилоном. Пропавшие и появившиеся комбинации ключей тоже видны.
WHERE o.revenue IS DISTINCT FROM n.revenue
OR o.rows_cnt IS DISTINCT FROM n.rows_cnt
ORDER BY ABS(COALESCE(n.revenue, 0) - COALESCE(o.revenue, 0)) DESC
LIMIT 200;
- Инвентаризация потребителей до начала. Список дашбордов, выгрузок, ML-пайплайнов, реверс-синков и людей, которые их используют. Обычно он вдвое длиннее ожидаемого, и половину пунктов находят по линиджу, а не опросом.
- Не переносить мусор. Миграция — единственный момент, когда легально не переносить 30 % витрин, которые никто не открывал год. Отчёт по обращениям из главы 11 даёт этот список за минуту.
- Отсечка с датой и владельцем. Без объявленной даты выключения старая платформа живёт вечно, и вы платите за две. Хвост в 10–15 % потребителей стоит половины бюджета проекта — это нормально и это надо заложить.
- Обратимость на всём протяжении. Пока не выключено старое, откат — это переключение источника дашборда, а не восстановление из бэкапа.
Общая механика крупных переходов разобрана в «Миграциях», а выбор и смена СУБД — в «Выборе и миграции баз данных».
7. Надёжность: что делать, когда всё сломалось
У платформы данных своя специфика восстановления: данные не «лежат в базе», а являются результатом цепочки вычислений. Это одновременно проблема и главный ресурс.
- RPO и RTO задаются по слоям, а не на платформу целиком. Потерять витрину не страшно — она пересчитывается. Потерять RAW — катастрофа: пересчитать не из чего. Отсюда правило: RAW и метаданные каталога защищаются как продакшн-база, витрины — нет.
- «Пересчитаем из RAW» — законная стратегия восстановления, если у неё измерено время. Пересчёт трёх лет истории может занять сутки; если бизнес этого не переживёт, нужны снапшоты витрин.
- Метаданные важнее данных. Потеря каталога Iceberg при живых файлах превращает озеро в набор безымянных Parquet-файлов. Каталог, метастор и состояние оркестратора должны иметь бэкапы и проверенное восстановление.
- Учения обязательны. «Восстановление из бэкапа» без проведённого теста — это гипотеза. Подходы — в «Хаосе и учениях».
- Инцидент в данных отличается от инцидента в сервисе тем, что последствия распространяются вниз по графу и могут потребовать пересчёта уже опубликованных чисел. Порядок действий — сдерживание, локализация по линиджу, backfill, объявление о пересчёте — разобран в главе о качестве; общий процесс реагирования — в «Реагировании на инциденты».
8. Решения фиксируются, а не пересказываются
Архитектура платформы живёт годами и переживает несколько поколений команды. Единственный способ не проходить одни и те же обсуждения заново — записывать решения вместе с контекстом и последствиями. Формат ADR (architecture decision record) для этого достаточен: что решили, какие были варианты, почему выбрали этот, что станет сигналом пересмотреть. Подробно — в «Архитектурных решениях».
Типичные решения платформы данных, которые обязательно должны быть записаны: выбор табличного формата и хранилища; модель партиционирования и зерно основных фактов; граница между ядром и доменными витринами; политика свежести по уровням данных; что покупается и что строится; правила именования и версионирования витрин.
9. Чек-лист зрелости
Быстрая самопроверка. Каждый пункт — либо «да, и это проверяется автоматически», либо «нет».
- Все источники приезжают через описанные конфигом коннекторы, а не через скрипты на чьём-то ноутбуке.
- RAW неизменяем и защищён бэкапом; всё остальное пересчитывается.
- У каждой Tier-1-витрины есть владелец, контракт, тесты и SLO свежести.
- Изменение модели проходит CI с unit-тестами и сравнением данных.
- Есть механизм отката релиза витрины без пересчёта.
- Стоимость разложена по потребителям, есть отчёт по топ-20 запросов.
- Линидж генерируется автоматически и используется при инцидентах.
- Проверки качества стоят до публикации, а не после.
- Персональные данные классифицированы, маскирование работает на уровне хранилища.
- Есть журнал изменений определений метрик, и потребители уведомляются.
- Восстановление платформы проверено учением, а не описано в документе.
- Витрины без обращений за 90 дней регулярно выявляются и отключаются.
- Архитектурные решения записаны и датированы.
Меньше восьми «да» — платформа держится на людях, а не на конструкции. Это не приговор, но это объясняет, почему всё ломается именно в отпуск ключевого инженера.
10. Типичные ошибки
- Архитектура на вырост. Kafka, Flink, Iceberg и mesh в компании, где данные помещаются в Postgres, — гарантированный техдолг без пользователей.
- Требование «в реальном времени» без обоснования решением. Самый дорогой параметр покупается по привычке.
- Data Mesh без платформы самообслуживания. Ответственность роздана, инструментов нет, единство определений потеряно.
- Свой оркестратор. Три человеко-года на повторение существующего.
- Витрины только в проприетарном диалекте. Стоимость выхода становится запретительной, и платформа перестаёт эволюционировать.
- Миграция без параллельного запуска и допусков. Числа разошлись, доверие потеряно, проект останавливается на середине.
- Миграция без даты отсечки. Две платформы навсегда и двойной счёт.
- Перенос всего, включая мусор. Бюджет утроен ради витрин, которые никто не открывает.
- Бэкап витрин вместо бэкапа RAW и метаданных. Защищено дешёвое, не защищено незаменимое.
- Решения живут в головах. Каждые полтора года платформу переизобретают заново, включая отвергнутые когда-то варианты.
11. Мини-итог
- Архитектура выводится из объёма, свежести, числа потребителей, числа источников, размера команды и регуляторики — именно в этом порядке.
- Свежесть — самый дорогой параметр; требование к ней должно опираться на решение, которое принимается по данным.
- Пакетный ELT поверх lakehouse — разумная основа; стриминг добавляется точечно, Lambda и Kappa нужны в узких случаях.
- Стадии зрелости проходятся последовательно; при переходе меняется модель владения, а не только стек.
- Data Mesh работает только вместе с платформой самообслуживания и автоматическим управлением; hub-and-spoke — рабочий компромисс.
- Build vs buy считается по совокупной стоимости владения за три года, включая стоимость выхода; открытые форматы — страховка от невозможности мигрировать.
- Миграция — это на 70 % миграция потребителей; параллельный запуск, объявленные допуски и дата отсечки обязательны.
- Защищать надо RAW и метаданные; витрины пересчитываются, если время пересчёта измерено.
- Решения записываются в ADR, иначе они будут приняты заново и, скорее всего, иначе.
Источники
- Nathan Marz, James Warren. Big Data: Principles and best practices of scalable realtime data systems — первоисточник Lambda-архитектуры: https://www.manning.com/books/big-data
- Jay Kreps. Questioning the Lambda Architecture — постановка Kappa: https://www.oreilly.com/radar/questioning-the-lambda-architecture/
- Michael Armbrust et al. Lakehouse: A New Generation of Open Platforms, CIDR 2021: https://www.cidrdb.org/cidr2021/papers/cidr2021_paper17.pdf
- Zhamak Dehghani. Data Mesh Principles and Logical Architecture: https://martinfowler.com/articles/data-mesh-principles.html
- Zhamak Dehghani. Data Mesh: Delivering Data-Driven Value at Scale, O’Reilly, 2022 — полная версия с разбором ограничений.
- Joe Reis, Matt Housley. Fundamentals of Data Engineering, O’Reilly, 2022 — жизненный цикл платформы и выбор компонентов: https://www.oreilly.com/library/view/fundamentals-of-data/9781098108298/
- Martin Kleppmann. Designing Data-Intensive Applications — фундамент под всеми решениями этой статьи: https://dataintensive.net/
- Michael Nygard. Documenting Architecture Decisions — формат ADR: https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions
- Google. Site Reliability Engineering, глава о восстановлении данных — почему бэкап без проверенного восстановления не бэкап: https://sre.google/sre-book/data-integrity/
Что дальше
Это последняя статья трека Data Engineering. Мы прошли весь путь: от способов движения данных до экономики платформы и её эволюции. Дальше начинаются соседние дисциплины, каждая из которых продолжает линию, оборванную здесь.
- Machine Learning — что происходит с данными после того, как вы их корректно отдали: постановка задачи, валидация, метрики качества моделей.
- Аналитика данных — сторона потребителя: как из ваших витрин получают выводы, и почему требования аналитика к данным именно такие.
- Нейронные сети — отдельный класс потребителей со своими требованиями к объёму и препроцессингу.
- Базы данных — устройство того, на чём всё это работает: индексы, транзакции, репликация, колоночные и объектные хранилища.
- Архитектурные паттерны — как дата-платформа встраивается в общую архитектуру: события, интеграции, границы сервисов.
- Платформенная инженерия и SRE — самообслуживание, эксплуатация, SLO и дежурство, без которых платформа данных не выходит из стадии «держится на людях».
- DDD — язык, на котором договариваются о смысле сущностей; половина споров о владении метрикой — это спор о границах контекста.
- Product Management — сторона, которая эти метрики заказывает: продуктовые метрики, эксперименты, приоритизация.
- Алгоритмы и Структуры данных — фундамент под всем, что мы обсуждали: сортировки и хэши в основе join’ов, вероятностные структуры в основе быстрых уникумов.
- Языковые треки, если хочется писать пайплайны руками: Python, Go, Elixir, TypeScript, C#.
Общая карта портала и рекомендованный порядок изучения — в роадмапе. Начать трек заново или свериться с картой можно с обзорной статьи.