Постановка проекта: аналитическая платформа на Trino
Этот модуль — capstone. Все предыдущие модули давали по части механики Trino: архитектура, жизненный цикл запроса, коннекторы, lakehouse, CBO, память, безопасность, наблюдаемость. Capstone собирает их в одно. Мы пройдём один сквозной проект — реальную аналитическую платформу — от пустого каталога до работающей и обслуживаемой системы. Шесть уроков модуля — это шесть этапов одного проекта, а не шесть отдельных тем.
Этот первый урок — постановка. Здесь мы фиксируем задачу, проектируем целевую архитектуру и принимаем ключевые технические решения. К проектированию относитесь серьёзно: ошибка архитектуры дороже любой ошибки в SQL.
Бизнес-задача
Вымышленная компания RetailScope — сеть розничных магазинов с интернет-продажами. Данные у неё разбросаны по трём местам, и это типичная ситуация:
- История продаж — события чеков и позиций, миллиарды строк, накапливаются годами. Лежат файлами в object storage.
- Справочники — товары, магазины, клиенты, категории. Живут в операционной базе PostgreSQL, обновляются ежедневно.
- Веб-аналитика — клики и просмотры с сайта, тоже большой объём, поступают батчами.
Бизнес хочет единую аналитику: выручка по категориям и регионам, динамика среднего чека, конверсия из просмотра в покупку, когортный анализ клиентов. Сейчас аналитики выгружают куски в Excel и сводят руками — медленно, ненадёжно, невоспроизводимо.
Требование к платформе: единая точка SQL-доступа ко всем данным; запросы по миллиардам строк за секунды-минуты; возможность строить и обновлять витрины; работа с историей данных (time travel); и всё это на открытых форматах, без вендор-лока.
Почему именно Trino + Iceberg + object storage
Связка не случайна — она прямо вытекает из требований.
Object storage (S3 или S3-совместимое хранилище) как слой хранения. Дёшево, масштабируется без потолка, отделяет хранение от вычислений. Миллиарды строк истории продаж экономично держать именно так, а не в дорогом warehouse.
Apache Iceberg как формат таблиц поверх файлов. Object storage сам по себе хранит только файлы — Iceberg добавляет поверх них семантику таблицы: схему, ACID-транзакции записи, эволюцию схемы, time travel через snapshots, hidden partitioning. Это открытый формат: данные не заперты внутри одного движка.
Trino как движок запросов. Он не хранит данные — он их запрашивает. MPP-исполнение даёт скорость на миллиардах строк; федеративность позволяет одним SQL соединить Iceberg-таблицы с PostgreSQL-справочниками, не копируя справочники в lakehouse. Единая точка SQL-доступа — это ровно роль Trino.
Ключевая мысль всего курса, и она же — фундамент этого проекта: Trino не база данных. Он ничего не хранит. RetailScope-платформа — это три раздельных слоя: object storage хранит байты, Iceberg придаёт байтам форму таблиц, Trino эти таблицы запрашивает. Разделение хранения и вычислений — не деталь, а главное архитектурное свойство: хранилище и кластер масштабируются независимо.
Что значит lakehouse и почему не warehouse
RetailScope строится как lakehouse — стоит проговорить, что это значит и почему не классический warehouse.
Классический data warehouse (Snowflake, Redshift, BigQuery) — это система, где хранение и движок запросов слиты воедино: данные грузятся внутрь warehouse в его собственном формате, и только его движок их читает. Это удобно и быстро, но имеет цену: данные заперты внутри вендора, а хранение и вычисления масштабируются и оплачиваются вместе.
Data lake — противоположная крайность: дешёвые файлы в object storage, любой движок может их читать, но нет ни схемы, ни транзакций, ни гарантий — «болото данных», в котором легко потеряться.
Lakehouse объединяет сильные стороны обоих. Файлы лежат в дешёвом object storage, как в lake, — но поверх них работает открытый формат таблиц (Iceberg), который добавляет схему, ACID-транзакции, time travel — то, что раньше было только в warehouse. Получается: дёшево и без вендор-лока, как lake, но со строгой семантикой таблиц, как warehouse.
| Свойство | Warehouse | Data lake | Lakehouse (RetailScope) |
|---|---|---|---|
| Хранение | Внутреннее, проприетарное | Файлы в object storage | Файлы в object storage |
| Схема и транзакции | Есть | Нет | Есть (через Iceberg) |
| Вендор-лок | Высокий | Низкий | Низкий |
| Хранение и compute | Слиты | Раздельны | Раздельны |
| Кто читает данные | Только свой движок | Любой движок | Любой движок |
Для RetailScope lakehouse — осознанный выбор: миллиарды строк истории продаж экономично держать в object storage, требование «открытые форматы, без вендор-лока» прямо исключает классический warehouse, а Iceberg возвращает строгость, которой не хватает голому lake.
Целевая архитектура
Вот целевая система. К ней мы будем идти все шесть уроков.
Разберём слои.
Источники. PostgreSQL — операционные справочники, подключается как каталог (postgresql). Object storage — файлы Iceberg-таблиц.
Catalog для Iceberg. Iceberg-таблице нужен каталог метаданных — компонент, который хранит указатель на текущую версию таблицы. Для проекта возьмём REST catalog: это современный, не привязанный к Hadoop вариант, разворачивается отдельным лёгким сервисом. (Альтернативы — Hive Metastore, AWS Glue, Nessie, JDBC catalog; их выбор разбирался в модуле про lakehouse.)
Trino-кластер. Координатор и воркеры. Координатор — точка входа, планировщик; воркеры исполняют задачи. Кластер видит два каталога: postgresql и iceberg.
Слои данных в Iceberg. Данные не валят в одну таблицу. Применяем многослойную модель: слой raw/staging — сырые продажи и веб-аналитика как есть; слой marts — денормализованные витрины под конкретную аналитику, построенные запросами поверх raw и справочников из PostgreSQL.
Потребители. BI-инструменты и аналитики обращаются к Trino через клиентов из прошлого модуля.
Ключевые архитектурные решения
Зафиксируем решения, на которых стоит проект. Каждое — с обоснованием.
| Решение | Выбор | Почему |
|---|---|---|
| Формат таблиц | Apache Iceberg | ACID, time travel, schema evolution, hidden partitioning, открытость |
| Хранилище | Object storage (MinIO как S3) | Дёшево, безграничный масштаб, отделение хранения от вычислений |
| Catalog метаданных | REST catalog | Современный, без Hadoop-зависимостей, лёгкий отдельный сервис |
| Справочники | Остаются в PostgreSQL | Малы и часто меняются; федерация дешевле копирования |
| Слои данных | raw / staging -> marts | Воспроизводимость, понятный lineage, переиспользование |
| Партиционирование фактов | По дню продажи | Соответствует типичным фильтрам аналитики по периодам |
| Развёртывание | docker-compose | Воспроизводимая среда; та же топология масштабируется в прод |
Два решения стоит прокомментировать особо.
Справочники остаются в PostgreSQL, а не копируются в Iceberg. Это сознательный выбор в пользу федерации. Справочники малы (тысячи-миллионы строк против миллиардов в фактах) и часто меняются. Копировать их в lakehouse — значит держать копию консистентной, то есть строить ещё один пайплайн. Trino умеет соединять PostgreSQL и Iceberg в одном запросе — пусть справочники живут там, где они уже актуальны. Федеративному слою посвящён урок 4.
Партиционирование фактов по дню продажи. Аналитика RetailScope почти всегда фильтрует по периоду — месяц, квартал, год. Партиционирование по дню (day()-transform Iceberg) даёт partition pruning под эти фильтры и при этом не порождает взрыв мелких партиций. Это прямое применение урока о тюнинге хранения из модуля 15.
Соблазн capstone — сразу писать SQL и грузить данные. Не поддавайтесь. Сначала — архитектура: какие слои, какой catalog, что федерируется, как партиционируется. Переделать схему партиционирования на таблице с миллиардом строк — это перезапись всей таблицы. Переписать запрос — минуты. Архитектурные решения принимают один раз и на этом этапе.
Границы проекта: что внутри, что вне
У хорошей постановки есть не только цель, но и явно очерченные границы — что проект делает и, не менее важно, чего он намеренно не делает.
В scope RetailScope: единый SQL-доступ ко всем данным через Trino; хранение фактов в Iceberg на object storage; федерация со справочниками в PostgreSQL; слоистая модель данных raw и marts; обслуживание Iceberg-таблиц; тюнинг запросов; базовая эксплуатация — безопасность, мониторинг, отказоустойчивость для тяжёлых нагрузок.
Сознательно вне scope несколько вещей, и каждую полезно проговорить. Загрузка данных из источников (extract-load) — это задача отдельных инструментов; Trino начинает работу, когда данные уже в object storage или PostgreSQL, ровно как dbt начинает с уже наполненного warehouse. Оркестрация — расписание пересборки витрин, зависимости между ними — это работа Airflow или dbt-trino поверх Trino, а не самого Trino. BI-слой — конкретные дашборды — это потребитель платформы, а не её часть. Стриминг — обработка событий в реальном времени — другой класс задач; RetailScope batch-ориентирован.
Airflow: оркестрация — это не часть Trino dbt: трансформации поверх Trino как отдельный инструментПонимать границы важно по той же причине, по какой dbt силён фокусом: платформа, которая пытается делать всё, не делает хорошо ничего. RetailScope — это слой аналитического SQL-доступа и моделирования поверх данных, и именно эту роль он должен выполнять отлично.
Критерий успеха проекта формулируется так: аналитик RetailScope может одним SQL-запросом получить выручку по категориям и регионам за любой период, запрос по миллиардам строк отрабатывает за секунды-минуты, витрины воспроизводимо пересобираются, доступна история данных, и платформа защищена, наблюдаема и переживает сбой воркера на тяжёлых нагрузках. Если в конце модуля это выполняется — проект состоялся.
План модуля
Шесть уроков — шесть этапов проекта RetailScope:
- Постановка (этот урок) — задача, архитектура, решения.
- Развёртывание — поднять кластер: координатор, воркеры, MinIO, REST catalog, каталоги.
- Загрузка и моделирование — данные в Iceberg, слои raw и marts, обслуживание таблиц.
- Федеративный слой — подключить PostgreSQL, соединить факты со справочниками, построить витрины.
- Тюнинг — статистика, чтение EXPLAIN ANALYZE, dynamic filtering, resource groups.
- Эксплуатация — безопасность, мониторинг, fault-tolerant режим, финальный обзор.
К концу модуля у вас будет работающая аналитическая платформа и, что важнее, понимание, как принятые на этом уроке решения проявляются на каждом следующем этапе.
Попробуй сам
Этот урок — проектный, и задание тоже проектное; кода пока нет.
- Перерисуйте архитектуру RetailScope от руки. Для каждого компонента (PostgreSQL, MinIO, REST catalog, координатор, воркер, слои raw и marts) напишите одним предложением, за что он отвечает.
- Для каждого из трёх источников RetailScope решите: попадёт он в Iceberg или останется federated-источником? Обоснуйте — объём данных и частота изменений.
- Сформулируйте, почему партиционирование фактов по году было бы плохим решением, а по часу — тоже плохим. Где середина и почему день?
- Представьте требование: «нужна выручка по категориям за прошлый квартал». Перечислите, какие компоненты архитектуры участвуют в обработке этого запроса и в каком порядке.
- Объясните своими словами, почему утверждение «давайте просто загрузим все три источника в одну Iceberg-таблицу» — архитектурная ошибка.
Цель — выйти из урока с ясной картой целевой системы, потому что все следующие пять уроков её строят.