Опыт внедрения Lakehouse: Trino + Iceberg поверх S3, с GitOps, мониторингом и отделением compute от storage
Зачем вообще трогать старую архитектуру
Изначальная платформа — классический MPP-DWH на Greenplum (shared-nothing). Проблема не в самой СУБД, а в том, что хранение и вычисления сцеплены: масштабирование «вширь» дорого, а хранение на дисках узлов — золотое. Добавьте сюда единую точку входа (GP) для тысяч внутренних пользователей, и вы получите:
- нельзя независимо масштабировать хранение и вычисления;
- ограниченная эластичность под пики;
- высокие косты за тёплое/холодное хранение.
Ингест до Lakehouse был типовым: источники → Kafka → Flink пишет Avro в S3 (raw) → Spark перегоняет в Parquet (ODS) → грузим в Greenplum, из которого все и ходят за данными. Это работало, но упиралось в стоимость и масштаб. (См. доклад «Lakehouse Meetup #3: Trino в Лемана Тех, Nessie в Азбуке Вкуса», на котором основан разбор.)
Целевое видение: Lakehouse
Требования к новой платформе: open source, разделение compute/storage, cloud-ready/agnostic, низкий порог входа. Реализация:
- Вычисления: Trino — ANSI SQL, федерация источников, активное сообщество.
- Табличный формат: Apache Iceberg — открытый формат таблиц с снимками, time-travel и DML через движки (в т.ч. Trino).
- Хранилище: S3-совместимый объектный стор (дешёвый, эластичный).
- Каталог метаданных: Hive Metastore (HMS) на старте, с планами миграции на Nessie (branching/коммиты и мульти-табличная атомарность на уровне каталога).
Кластера Trino по ролям нагрузки:
- Ad-hoc (BI/аналитики) — интерактивные запросы;
- ETL — технические учётки, пакетная обработка;
-
DQ — правила качества данных.
Аутентификация через Keycloak + AD, авторизация — file-based ACL (JSON-правила), как встроённый механизм Trino.
Почему именно такой стек
Trino
- Универсальная «SQL-надстройка» над озером и источниками; поддержка Iceberg, Glue/HMS/REST/Nessie-каталогов; развитые коннекторы.
- Есть ограничения: нет временных таблиц (CREATE TEMP TABLE не поддерживается), из альтернатив — memory-connector/временные представления или staging-таблицы.
- «Спиллы» на диск и FTE (fault-tolerant execution) конфигурируются; FTE повышает надёжность ценой задержки — команда Лемана Тех предпочла перезапуск упавших задач вместо включения FTE.
Iceberg
- Снимки/временные версии, DML (INSERT/UPDATE/DELETE/MERGE) через Trino, row-level deletes на spec v2 — критично для SCD/CDC.
- Атомарность на уровне одной таблицы. Нативных multi-table транзакций в самом Iceberg нет; их даёт Nessie (git-подобные ветки и атомарные коммиты «сквозь» несколько таблиц).
Каталоги
Iceberg поддерживает HMS, Glue, JDBC, REST, Nessie — это упрощает миграции и «data-as-code» подход.
Архитектура по слоям
- Raw (S3/Avro): Flink пишет потоковые изменения (опыт и компетенции команды в Avro — аргумент «за»).
- ODS (S3/Parquet): Spark нормализует формат и схемы.
- Lakehouse-таблицы (Iceberg): поверх тех же данных читают разные движки (Trino, Spark), одни и те же таблицы доступны множеству consumers.
- Выделенные кластера Trino: ad-hoc / ETL / DQ. Настраивать resource groups не стали — изоляция достигается раздельными кластерами, что проще в эксплуатации. (В Trino при желании есть file/db-менеджер ресурс-групп.)
Доступ и безопасность: Keycloak (OIDC/JWT) + file-based ACL в Trino; при необходимости можно перейти на Ranger/OPA.
Управление инфраструктурой: GitOps + ArgoCD + Vault; откаты версий «в одно действие». (Подход типовой для Kubernetes-стека Trino; helm-чарт Trino это хорошо поддерживает.)
Мониторинг и наблюдаемость
- Системные метрики Trino: JMX/OpenMetrics → Prometheus → Grafana. Для экспорта JMX метрик используют jmx_prometheus_javaagent; это стандартная практика.
- Хранилище метрик: Prometheus Operator ↔ VictoriaMetrics (remote-write) — удобно для длительного хранения.
- Логи запросов: встроенный event listener Trino → Kafka → ClickHouse → Grafana-дашборды. (Kafka/HTTP event listener — штатная фича Trino.) Дашбордный пресет «Grafana Trino Overview» выложен в open-source.
Практический нюанс: стандартный UI Trino не хранит историю после рестартов координатора, поэтому вынос query-логов в Kafka/CH — must have для аудита и анализа нагрузки.
Миграция: как «пересадить» пользователей с GP на Trino
- Пилотные витрины: переносим 2–3 ключевые витрины/запросы как эталон, измеряем латентность, стоимость, стабильность.
- Семантика и SQL-совместимость: максимально сохраняем тексты запросов; для тяжёлых JOIN/MERGE — пересматриваем партиционирование, bucketing и сортировку в Iceberg. (Trino Iceberg поддерживает MERGE, UPDATE/DELETE, но обратите внимание на скан целевой таблицы — помогает продуманная партиция и фильтры.)
- Доступы: воспроизводим роли/маски/строчные фильтры в правиле-файлах (или сразу смотрим в сторону Ranger/OPA — удобнее на масштабах).
- Обучение: «SQL одинаковый, семантика — нет»: объясняем аналитикам, что временных таблиц нет, как жить со staging, как запускать интерактив без «поджигания» ETL-кластера.
Результаты
- Экономика: хранение в объектном сторе дешевле на порядок; масштабирование — через Kubernetes, без предварительного «резервирования» дисков. (По докладу компании.)
- Производительность: многие витрины ускорились за счёт простого горизонтального скейлинга кластеров и лучшего планирования; однако точечно GP на SSD быстрее Trino ~на 20% — это ожидаемо для сильно оптимизированных MPP на локальных SSD. (По докладу.)
- Гибкость: одни и те же Iceberg-таблицы читают разные движки; Trino даёт вторую точку входа для аналитиков без дублирования данных.
Риски и как их снимать
1) «Много мелких файлов» в S3.
Симптомы: деградация планирования/сканов. Лечение: регулярные процедуры rewrite_data_files / rewrite_manifests, настройка размеров файлов, батч-ингест.
2) Рост метаданных и «снежный ком» снимков.
Лечение: expire_snapshots и remove_orphan_files по расписанию (например, ежедневно/еженедельно).
3) Отсутствие multi-table транзакций.
Снимать через Nessie (ветки/коммиты/atomic multi-table), либо через управляемые «фазы публикации» (WAP: write-audit-publish).
4) MERGE может читать «всю цель».
Помогает грамотное партиционирование, bucketing, использование фильтров по partition/identity, staging помладших диапазонов.
5) FTE медленный.
Для ETL-кластера зачастую прагматичнее ретраи на уровне оркестратора и перезапуск. (Документация описывает FTE/ретраи, но выбор — компромисс производительность↔надёжность.)
6) Контроль доступа «файлами» сложен на масштабе.
При росте числа правил переходите на Ranger/OPA; file-based хорош как старт.
Эксплуатация: как поддерживать столы Iceberg в здоровом состоянии
- Ежедневно: expire_snapshots (min ретеншен ≥ 7d), агрегировать/уплотнять файлы, контролировать % мелких файлов.
- Еженедельно: rewrite_data_files (бин-пэкинг), rewrite_manifests, analyze/статистика (если задействована).
- Постоянно: отслеживайте рост таблиц метаданных, orphan-files, и держите автоматизацию (Spark/Trino процедуры) в Cron/Argo Workflows.
Практика SCD2 на Iceberg + Trino (кратко)
- Append-only changelog в «журнал» + периодический MERGE в «текущую» таблицу с управлением флагами активности/диапазонами дат — простой и надёжный подход на больших объёмах.
- Прямой MERGE из staging в «медленно меняющуюся» таблицу с партиционированием по датам/ключам, бакетированием по business-key для ускорения сопоставления. Trino Iceberg поддерживает MERGE/UPDATE/DELETE и row-level deletes (spec v2).
- На высоких SLA — разнесите WAP (ветка/каталог → аудит → публикация/fast-forward) через Nessie.
Почему это сработало организационно
- Простая модель владения: кластера разделены по типу нагрузок вместо тонкой настройки resource groups. (RG в Trino есть, но их можно включить позже, когда потребуются очереди/квоты.)
- GitOps: инфраструктура как код + быстрые откаты; единообразные релизы конфигов/каталогов/шардов Trino.
- Порог входа для аналитиков: SQL тот же, данные — те же, но читаются из Iceberg через Trino; часть запросов переносится «как есть».
Чек-листы
А) Переход на Lakehouse
- Зафиксируйте целевые SLO/стоимость и измерьте базовую линию на GP.
- Выберите каталог (HMS сейчас, Nessie — план) и оформите naming/бизнес-глоссарий.
- Спроектируйте партиционирование/бакетирование для топ-витрин.
- Разделите кластера Trino по нагрузкам, включите аутентификацию (Keycloak) и file-ACL.
- Проложите мониторинг: JMX/OpenMetrics → Prometheus → VictoriaMetrics, query-events → Kafka → ClickHouse → Grafana (установите open-source пресет).
- Пилот: 2–3 витрины end-to-end, freeze требований, решите «острые» запросы (временные таблицы, MERGE).
Б) Ежедневная эксплуатация
- expire_snapshots/remove_orphan_files по расписанию;
- контроль «мелких файлов» и периодический rewrite_data_files;
- аудит запросов в ClickHouse и алерты по SLA «длина очереди/время старта/пролёт памяти».
В) Безопасность и доступ
- Единый IdP (Keycloak/AD), mTLS, file-ACL как старт; Ranger/OPA — когда правил становится много.
Часто задаваемые вопросы (по мотивам доклада)
Как разделили ресурсы?
Ресурсные группы не настраивали — нагрузку разделили кластерами: ad-hoc/ETL/DQ. (В Trino RG есть; будут нужны — включим.)
Сравнение производительности Greenplum и Trino?
В среднем Trino медленнее GP примерно на 20%, если у GP всё на SSD, но выигрывает за счёт эластичности и изоляции нагрузок. (По докладу Лемана Тех.)
Рассматриваете Paimon как каталог?
Пока не тестировали; к выбору каталога подходят итеративно. (Iceberg поддерживает HMS/Glue/JDBC/REST/Nessie — есть куда расти.)
Почему выбрали Avro в raw?
Инженеры знакомы с технологией и она соответствует требованиям пайплайна Flink→S3. (Из доклада.)
Данные «присылают» или вы «забираете»?
Сервисная служба настраивает Debezium в общую Kafka-шину, платформа данных снимает потребление сама — команды источников не трогаем. (Из доклада.)
Как боретесь с «россыпью» файлов в S3?
Пока — вручную/по расписанию; в планах полная автоматизация rewrite_data_files / rewrite_manifests.
Используете FTE (Fault-tolerant execution) в Trino?
Нет — слишком медленно для наших нагрузок; предпочитаем ретраи/перезапуски.
Что используете для ускорения запросов в Iceberg?
Партиционирование и бакетирование; сортировка пробовалась, большого профита не дала. (Из доклада.)
Как обеспечиваете High Availability?
Пока без избыточных координаторов; падений координатора не наблюдали. (Из доклада.)
Почему выбрали HMS?
Нужен был единый каталог для смешанного доступа к Parquet/Iceberg — Hive Metastore решает. (Iceberg из коробки работает с HMS.)
Почему нет временных таблиц?
Trino не поддерживает CREATE TEMP TABLE — используйте memory-каталог/временные вью/промежуточные Iceberg-таблицы.
Как мониторите запросы?
Kafka/HTTP event listener → Kafka → ClickHouse → Grafana; пресет дашбордов в open-source.
Итог
Переезд на Lakehouse (Trino + Iceberg поверх S3) дал Лемана Тех разделение вычислений и хранения, эластичность и заметную экономию, сохранив при этом понятный SQL-интерфейс для пользователей. Важно: признать ограничения (временные таблицы, multi-table транзакции) и закрыть их инженерно — ветвлением/публикацией через Nessie, грамотным дизайном таблиц и дисциплиной обслуживания Iceberg.
Если вы стартуете сегодня, минимальный «скелет» выглядит так: S3 + Iceberg (HMS сейчас, план на Nessie) + Trino-кластера по ролям + GitOps + Prometheus/Victoria + Kafka event listener → ClickHouse → Grafana. Этот путь проверен на больших объёмах — и соотношение «стоимость/гибкость» у него очень конкурентное.



