Привет, Хабр! Меня зовут Александр, я DevRel команды Selena Lakehouse. Пишу про СУБД StarRocks, архитектуры Lakehouse и Streamhouse в Telegram-канале @starrocks_selena (https://t.me/starrocks_selena).
Полгода назад термин Streamhouse начал всплывать на конференциях и в блогах. При этом многие русскоязычные источники, которые я читал, сводят его к «замене Iceberg на Paimon и обновлению Flink» или путают с обычным Lakehouse. На самом деле за Streamhouse стоит интересная архитектурная логика. Конкретный набор компонентов, где каждый решает свою задачу: Apache Flink для вычислений, Apache Fluss как горячий потоковый слой, Apache Paimon как холодное хранилище. Вместе они дают потоковый Lakehouse с задержкой в секунды вместо минут.
Мне стало интересно: можно ли на этом стеке построить полноценный аналитический конвейер? Не на слайдах, а руками в Docker Compose, с SQL и реальным сценарием.
В этой статье:
Разбираем архитектуру Streamhouse. Какие компоненты, зачем каждый из них нужен и как они связаны.
Собираю конвейер для телеком-оператора. В Docker Compose, с SQL, и скоростью генерации событий — 2000 событий/сек.
Упираюсь в ограничение. Конвейер работает, данные есть, а быстро анализировать их нечем.
Нахожу решение и добавляю недостающий компонент (спойлер: StarRocks) и показываю результат с бенчмарками.
Для кого: дата-инженеры и архитекторы, которые строят конвейеры аналитики реального времени и хотят понять, стоит ли смотреть в сторону Streamhouse, и что там работает, а что пока нет.
1. Проблема Lakehouse: минутный потолок
Lakehouse-форматы (Iceberg, Hudi, Delta Lake) построены на модели неизменяемых файлов (Parquet/ORC) на объектном хранилище плюс слой метаданных. Эта модель хорошо работает для пакетной аналитики, но при потоковой записи возникают конкретные ограничения.
Четыре источника задержки:
Накладные расходы фиксации. Каждая фиксация — это запись Parquet-файла + обновление манифеста + атомарная замена метаданных. При потоковой записи через Flink каждый чекпоинт (обычно раз в 10–30 секунд) инициирует коммит в Lakehouse-формат. Это создаёт постоянную нагрузку на объектное хранилище.
Мелкие файлы. Частые фиксации порождают тысячи мелких Parquet-файлов. При фиксации каждые 30 секунд за сутки накопится ~2880 коммитов на одну таблицу. Но каждый writer (параллельный поток) создаёт свой файл, при параллелизме 8 это уже ~23 000 файлов в сутки. И каждый файл несёт метаданные, footer, схему.
Compaction. Для борьбы с мелкими файлами нужен отдельный процесс, периодическая перезапись в крупные файлы. Это дополнительные ресурсы, сложность и окна обслуживания.
Обновления по ключу. Модель неизменяемых файлов не поддерживает обновления на месте. Нужны файлы удаления (delete files), слияние при чтении, всё это деградирует пропорционально доле обновлений.
Когда я в первый раз столкнулся с этим на практике, это была подготовка к пилоту по Iceberg и Lakehouse. Заказчик ожидал относительно быстрое выполнение запросов, а получил десятки минут ожидания — тысячи мелких файлов после потоковой записи, а compaction только добавлял нагрузку вместо того чтобы помогать. Тогда я понял одну вещь: если в задаче не нужны транзакции и time travel, Lakehouse-формат может оказаться не ускорителем, а проблемой. И мы предложили другие архитектуры и компоненты для решения его задачи.
Уточнение: это не означает, что Lakehouse плох. Для аналитики с задержкой 5-15 минут — это отличная архитектура. Но при потоковой записи с частыми обновлениями модель неизменяемых файлов ставит перед выбором: свежесть данных против стоимости эксплуатации.
В итоге компании строят двойную инфраструктуру: Kafka + Flink для потоковой обработки плюс Iceberg для аналитики. Данные живут в двух местах, схемы рассинхронизируются, а инженеры тратят время на синхронизацию.
Ververica (компания, основанная создателями Apache Flink) предложила модель LSR-треугольника (Lakehouse — Streamhouse — Real Time), которая описывает баланс (https://www.ververica.com/blog/streamhouse-unveiled) между задержкой и стоимостью:
Lakehouse (Iceberg/Delta/Hudi): минуты-часы задержки, дёшево ($)
Streamhouse (Flink+Fluss+Paimon): секунды, умеренно ($$)
Потоковая обработка (Kafka/Fluss напрямую): миллисекунды, дорого ($$$$)

Streamhouse предлагает один путь записи с автоматическим перемещением данных между горячим и холодным слоем — задержка в секунды вместо минут, без двойной инфраструктуры и ручной синхронизации.
2. Стек: Flink + Fluss + Paimon
Изначально Ververica (компания, основанная создателями Flink) определила Streamhouse (https://www.ververica.com/blog/streamhouse-unveiled) как комбинацию трёх компонентов: Flink CDC (ingestion) + Apache Flink (вычисления) + Apache Paimon (хранение). Эта комбинация покрывала потоковый ETL, но не решала проблему горячего слоя. Свежие данные становились доступны для запросов только после очередного чекпоинта Flink (обычно раз в 10–30 секунд), а до этого момента они просто висели в памяти движка.
В конце 2024 году Ververica представила Apache Fluss (https://www.ververica.com/blog/introducing-fluss) колоночное потоковое хранилище, которое встаёт между Flink и Paimon как горячий слой. Fluss обеспечивает субсекундный доступ к свежим данным, а встроенный тиринг-сервис автоматически переносит их в Paimon. С появлением Fluss стек обновился, именно его мы проверим на тестовом стенде дальше в статье:
![Архитектура Streamhouse (перерисована по [Introducing Fluss Ververica] (https://www.ververica.com/blog/introducing-fluss)): Flink(вычисления) → Fluss (горячий слой) → Paimon (холодный слой). Архитектура Streamhouse (перерисована по [Introducing Fluss Ververica] (https://www.ververica.com/blog/introducing-fluss)): Flink(вычисления) → Fluss (горячий слой) → Paimon (холодный слой).](https://habrastorage.org/r/w1560/getpro/habr/upload_files/476/990/47b/47699047bbea08d26ec18d2652db3988.png)
Три компонента, каждый со своей ролью.
Apache Flink - вычислительный движок
Flink это единственный движок, который нативно работает и с Fluss, и с Paimon через SQL (возможно когда вы читаете эту статью Spark тоже уже подтянулся). В Streamhouse он выполняет три роли:
Потоковые вычисления — обработка, обогащение, соединения (JOIN) в реальном времени.
Пакетные запросы — аналитика по историческим данным в том же движке.
Управление конвейером — координация записи, тиринга и компактации
В марте 2025 года вышел Flink 2.0 (https://flink.apache.org/2025/03/24/apache-flink-2.0.0-a-new-era-of-real-time-data-processing/), для Streamhouse это важно: разделённое хранение состояния (ForSt) позволяет держать состояние JOIN-операций на диске, а не в памяти, что критично для обогащения потоков по большим справочникам. Асинхронная модель выполнения снижает задержку чекпоинтов, а оптимизированные многосторонние JOIN ускоряют именно те операции, на которых строится потоковый конвейер. На тестовом стенде, который мы развернём в третьей главе, будет Flink 1.20 и Fluss 0.8 (пока предоставляет quickstart-образ только для этой версии).
Apache Fluss - горячий слой
Fluss — это колоночное потоковое хранилище для аналитики реального времени. Проект в инкубаторе Apache с июня 2025, обкатан в Alibaba при пиковой нагрузке 40 ГБ/с на кластере объёмом 3 ПБ (https://fluss.apache.org/blog/fluss-joins-asf/).
Kafka проектировался для передачи событий, а не для аналитических запросов. Fluss закрывает конкретные пробелы:
Kafka | Fluss | |
Формат хранения | Строковый (byte array) | Колоночный (Arrow IPC) |
Отсечение колонок | Нет | Да, серверное (до 10× прироста при отсечении 90% колонок) |
Обновления по ключу | Нет (append-only) | Нативные (PK-таблицы) |
Тиринг в Lakehouse | Kafka Connect (внешний) | Встроенный тиринг-сервис |
Аналитические запросы | Не предназначен | Column pruning + SIMD |
Fluss в переводе с немецкого — «река». В Apache-проектах часто неравнодушны к воде: streams, data lakes, Lakehouse, теперь река. Осталось дождаться Apache Ozean — и круговорот данных в природе замкнётся.
Подробно различия и сходства Kafka и Fluss разобраны в статье «Why Fluss?» на официальном сайте проекта (https://fluss.apache.org/blog/why-fluss/).
Главная интеграция — это тиринг-сервис: отдельный Flink-джоб, поставляемый в комплекте с Fluss, который переносит данные из Fluss в Paimon (Arrow IPC -> Parquet) напрямую, без промежуточной сериализации. Тиринг управляется параметром при создании Fluss-таблицы через Flink SQL:
'table.datalake.enabled' = 'true', 'table.datalake.freshness' = '30s'
Каждые 30 секунд данные автоматически перемещаются в холодный слой.
Объединённое чтение (Union Read)
Архитектурная возможность Streamhouse это Union Read. Один SQL-запрос через Flink прозрачно объединяет данные из горячего (Fluss) и холодного (Paimon) слоёв. Для пользователя это выглядит как одна таблица, а внутри Flink автоматически:
Читает свежие данные из Fluss (те, что ещё не перенеслись в Paimon).
Читает исторические данные из Paimon (Parquet-файлы).
Объединяет результат и дедуплицирует по первичному ключу.

Apache Paimon - холодный слой
Apache Paimon — это формат таблиц для потокового Lakehouse (Top-Level Project Apache с апреля 2024). Ключевое отличие от Iceberg: вместо модели неизменяемых файлов Paimon использует LSM-деревья (Log-Structured Merge Tree), ту же структуру данных, что и в RocksDB и Cassandra.
Почему это важно для Streamhouse:
Запись всегда быстрая. Данные буферизуются в MemTable в памяти, периодически сбрасываются на диск как отсортированные файлы. Никакой перезаписи существующих файлов.
Обновления по ключу нативные. Не нужны файлы удаления (delete files). LSM-дерево при чтении объединяет версии записи по ключу, отдавая последнюю.
Compaction встроенный. Фоновый процесс автоматически объединяет мелкие файлы в крупные, не блокируя запись.
Двойная природа. Одна и та же таблица работает и как обычная таблица (пакетный режим с полным снимком), и как очередь сообщений (потоковый режим с журналом изменений). Отдельная инфраструктура Kafka не нужна.
Paimon поддерживается Flink, Spark, Trino, Presto и рядом других движков. Paimon может генерировать метаданные Iceberg (V2 для обычных таблиц, V3 для таблиц с deletion vectors), позволяя читать данные через любой движок с поддержкой Iceberg.
А можно ли просто взять Iceberg вместо Paimon? Формально - да, Fluss с версии 0.7 поддерживает тиринг и в Iceberg. Но в модели неизменяемых файлов (типа Iceberg) обновления по ключу требуют delete files и merge-on-read, те самые проблемы, которые мы разобрали в главе 1. Paimon с его LSM-деревом обновляет записи нативно, без delete files и без деградации при большой доле обновлений. Для Streamhouse-конвейера с частыми обновлениями справочников (PK-таблицы) и потоковым обогащением Paimon подходит лучше.
Обратите внимание: в документации Paimon (https://paimon.apache.org/docs/1.0/engines/overview/) явно перечислены рекомендуемые аналитические движки для запросов - StarRocks, Trino и другие. Paimon сам по себе это формат хранения, а не движок запросов. Запомните этот момент.
3. Телеком-кейс: строим конвейер
Красивые архитектурные схемы — это одно, а работающий конвейер с реальной нагрузкой, совсем другое. Мне хотелось понять, как Streamhouse ведёт себя на практике: сколько данных проходит без потерь, какая реальная свежесть, где начинаются ограничения. Единственный способ выяснить — это развернуть стек на виртуальной машине и эмулировать работу оператора связи (мой любимый кейс для NRT).
Сервер: VM, 8 vCPU (AMD EPYC), 32 ГБ ОЗУ.
Docker Compose (7 контейнеров):
ZooKeeper 3.9.2
Fluss 0.8.0 CoordinatorServer
Fluss 0.8.0 TabletServer
Flink 1.20.1 JobManager
Flink 1.20.1 TaskManager
MinIO (S3-совместимое хранилище)
Генератор данных

Сценарий
~500 базовых станций по 12 регионам. ~100 000 абонентов с тарифами (Базовый, Стандарт, Премиум, VIP, Бизнес). Поток CDR-событий (Call Detail Records) со скоростью 2000 событий/сек — звонки, SMS, передача данных, обрывы (CALL_DROP), ошибки хэндовера (HANDOVER_FAIL). Это сопоставимо с нагрузкой оператора на 5—10 млн абонентов по голосу и SMS; крупные операторы с data-трафиком генерируют на порядок больше.
«Золотая тысяча» — это VIP-абоненты (subscriber_id 1-1000), для которых обрывы и инциденты нужно обнаруживать в секунды, а не в минуты. У этих абонентов высокий ARPU (средний доход на абонента) и персональный SLA. Один пропущенный инцидент может стоить оператору контракта. Для остальных абонентов допустим агрегированный мониторинг с задержкой в минуты.
Примечание: кстати, я рассказывал про этот кейс с другой стороны на прошлогоднем SQL-ниндзя вот запись(https://www.youtube.com/watch?v=OY0CUGNdxGs&t=492s), там подробнее про real-time аналитику. Забавный факт: в том видео я упоминаю, что познакомился со StarRocks случайно именно в этом кейсе, а теперь работаю с ним на full-time.
Конвейер: SQL-команды, ноль кода

Шаг 1. Одной CREATE CATALOG подключаем Flink к Fluss. Дальше создаём три таблицы обычным CREATE TABLE, никаких 'connector' = '...' указывать не нужно, потому что каталог Fluss уже знает, куда и как писать. Запускаем три потока загрузки данных (каждый это отдельный Flink-джоб): справочник станций, справочник абонентов, поток CDR-событий.
Все SQL-скрипты для всех таблиц (CREATE CATALOG, CREATE TABLE, INSERT INTO) в комментариях к статье.
Шаг 2. Обогащение «3-way» Lookup JOIN. Lookup JOIN — это механизм Flink, при котором для каждой записи из потока выполняется точечный запрос (lookup) в справочную таблицу по первичному ключу. В отличие от обычного JOIN, который требует хранить обе стороны в памяти, Lookup JOIN обращается к справочнику на лету — это эффективно для обогащения потока данными, которые меняются редко. В нашем случае каждое CDR-событие обогащается данными абонента (имя, тариф) и станции (регион) через два Lookup JOIN по PK-таблицам Fluss, отсюда «3-way». Ключевой параметр — table.datalake.freshness = 30s, который запускает автоматический тиринг в Paimon каждые 30 секунд.
Итого: 5 потоковых Flink-джобов, запущенных SQL-командами (ни строчки Java/Python):
Загрузка справочника станций.
Загрузка справочника абонентов.
Загрузка потока CDR-событий.
Тиринг-сервис (Fluss → Paimon).
Обогащение с 3-way Lookup JOIN.
Результат: работает!

Конвейер запущен, данные текут. За пару минут в Fluss накапливаются сотни тысяч обогащённых событий. Тиринг-сервис каждые 30 секунд переносит их в Paimon, Parquet-файлы аккуратно формируются в S3. Flink UI показывает стабильный throughput без backpressure.
Streamhouse на этапе ETL без нареканий. Данные исправно текут от генератора через Flink в Fluss и дальше в Paimon. Следующий логичный вопрос: А как аналитик может использовать эти данные для принятия решений?
4. А теперь – аналитика! А Flink SQL упирается в стену
Конвейер работает: 2000 CDR-событий в секунду обогащаются, переносятся в Paimon, за несколько минут накапливается более полутора миллионов строк. Данные есть. Но складировать данные — не цель. Их нужно использовать для принятия решений.
Представьте: вы руководитель технической службы телеком-оператора. Вам нужен дашборд, который обновляется каждые 30 секунд и показывает:
Сколько событий обработано прямо сейчас?
Какие VIP-абоненты теряют связь?
В каких регионах больше всего инцидентов?
Как меняется ситуация по часам?
У нас есть Flink SQL, который умеет работать и в пакетном режиме. Почему не в потоковом? Потому что потоковый режим Flink предназначен для непрерывных вычислений (INSERT INTO, Lookup JOIN, обогащение). А нам нужен разовый ответ на конкретный вопрос: «покажи TOP-10 прямо сейчас». Для этого переключаем execution.runtime-mode на batch и пробуем.
Запрос первый: Сколько событий?
SET 'execution.runtime-mode' = 'batch'; SELECT COUNT(*) AS total_events FROM enriched_events$lake;
Примечание: суффикс
$lake(https://fluss.apache.org/docs/streaming-lakehouse/integrate-data-lakes/paimon/) — задокументированный механизм Fluss, который указывает Flink читать только холодный слой Paimon. Таблица ведёт себя как обычная Paimon-таблица.
Ответ: 1 647 099 строк. Но пришёл через 7–12 секунд. Простой COUNT и больше 7 секунд? Но дело в том, что Flink не хранит агрегаты наготове. Он запускает полноценный batch-джоб: планирует граф выполнения, поднимает задачи, последовательно читает все Parquet-файлы Paimon, считает строки и возвращает результат. Это пакетный процесс, а не мгновенный ответ от OLAP-движка.
Для разового запроса – терпимо. Но вспомним требование: дашборд обновляется каждые 30 секунд. Виджет с COUNT должен обновиться быстрее, чем придёт ответ на предыдущий запрос, а он не успевает.
Запрос второй: Кто из VIP теряет связь?
Настоящие вопросы бизнеса сложнее COUNT. Для дашборда оператора нужны: TOP-10 VIP-абонентов по инцидентам (кому звонить прямо сейчас), тепловая карта по регионам (где проблемы), часовой тренд (как меняется ситуация). Запросы это стандартные GROUP BY + ORDER BY + агрегации по таблице enriched_events$lake.
Все SQL-запросы аналитики (с полными колонками и метриками) и их результаты в комментариях к статье.
Результат: 15-25 секунд на 1.6M строк за каждый запрос. Flink честно сканирует все Parquet-файлы, строит хэш-таблицу группировки, сортирует. Для batch-движка — ожидаемый результат. Для интерактивного дашборда — нет. И это только один запрос.
Проблема: один запрос за раз
Дашборд — это не один запрос. Это 5–8 виджетов, каждый обновляется каждые 30 секунд. Плюс несколько аналитиков одновременно.
Flink SQL в batch-режиме выполняет запросы последовательно. У него нет конкурентных сессий, нет пула соединений, нет cost-based оптимизатора для ad-hoc запросов. Flink создавался для долгоживущих потоковых задач, а не для интерактивной аналитики.
Математика: 5 виджетов × 15 секунд = 75 секунд на один цикл обновления дашборда. При требуемом интервале 30 секунд запросы не успевают завершиться до начала следующего цикла.
Итого, что мы выяснили
Streamhouse отлично решает задачу доставки данных: Flink обогащает поток, Fluss обеспечивает горячий слой, Paimon принимает в LSM-дерево. Как ETL-конвейер — работает безупречно.
Но между хранилищем и экраном аналитика, руководителя есть разрыв. Paimon — это формат хранения, не движок запросов. Flink — это потоковый вычислитель, не OLAP-система. Документация Fluss прямо указывает (https://fluss.apache.org/docs/maintenance/tiered-storage/lakehouse-storage/), что для аналитики по холодному слою рекомендуются внешние движки запросов. Документация Paimon перечисляет (https://paimon.apache.org/docs/1.0/engines/overview/) StarRocks, Trino, Spark и другие.
Нам нужен MPP-движок!
5. Добавляем StarRocks

Раз архитектура сама подсказывает, что нужен аналитический движок, попробуем. Документация Paimon перечисляет несколько вариантов: StarRocks, Trino, Spark и другие. Все они умеют читать Paimon-таблицы через внешние каталоги. Я выбрал StarRocks, во-первых, потому что работаю в компании, которая делает из него Enterprise-решение и достаточно по нему экспертизы, во-вторых, потому что MPP-архитектура StarRocks оптимизирована именно для интерактивных запросов с низкой задержкой. На стенде, StarRocks 4.0.6 в одном Docker-контейнере (поддержка Paimon через внешний каталог доступна с версии 3.1).
Подключение, одна SQL-команда:
CREATE EXTERNAL CATALOG paimon_lake PROPERTIES ( "type" = "paimon", "paimon.catalog.type" = "filesystem", "paimon.catalog.warehouse" = "s3://paimon/warehouse", "aws.s3.endpoint" = "http://minio:9000", "aws.s3.access_key" = "admin", "aws.s3.secret_key" = "password", "aws.s3.enable_path_style_access" = "true" );
Одна SQL-команда, и StarRocks видит все таблицы Paimon. Никакого ETL, никакого копирования данных, никакого импорта. StarRocks читает Parquet-файлы Paimon напрямую из S3 (MinIO), те самые файлы, которые создаёт тиринг-сервис Fluss. Данные существуют в одном экземпляре, просто два движка обращаются к ним для разных задач.
Те же три запроса, а результат другой
Запускаем точно те же запросы, что работали медленно через Flink SQL. Streaming-джобы в Flink продолжают работать, конвейер обогащения и тиринга не останавливаем. StarRocks обращается к Paimon через собственный каталог, полностью независимо от Flink. Единственное изменение в SQL, вместо enriched_events$lake пишем paimon_lake.telecom.enriched_events.
COUNT(): 1,2 сек (было 7–12 сек через Flink SQL) - ускорение в 6–10 раз.
TOP-10 VIP по инцидентам: 2,4 сек (было 15–25 сек через Flink SQL) – 6–10 раз.
Тепловая карта по регионам: 3.0 сек на 1.6M строк (было 15–25 сек) – 5–8 раз.
Уточнение: 1-3 секунды — это режим External Catalog: прямое чтение из S3 одной SQL-командой, без копирования данных и без дополнительного тюнинга параметров. Если для дашборда нужны миллисекунды, достаточно создать Materialized View с автообновлением — данные обновляются из Paimon каждые 60 секунд, а те же запросы ускоряются в 30 раз минимум: COUNT за 10 мс, TOP-10 VIP за 30 мс, тепловая карта за 25 мс.
Скорость серии запросов
Запускаем пять запросов последовательно к StarRocks, один за другим, без пауз. Все пять выполняются за ~20 секунд (~4 секунды на запрос). Для сравнения: через Flink SQL те же пять запросов заняли бы 75+ секунд последовательно. На нашем стенде это один контейнер StarRocks, читающий из S3 (MinIO), в продакшен-кластере с локальным SSD и несколькими BE-нодами эти цифры будут лучше.
Тут надо оговориться
StarRocks — это не потоковый движок обработки данных. Он не конкурирует с Flink или Fluss. В этой архитектуре StarRocks читает только холодный слой (Paimon). Свежие данные, которые ещё находятся в Fluss и не перенеслись в Paimon, для StarRocks недоступны. Свежесть данных для аналитики ограничена частотой тиринга, на нашем стенде это 2–37 секунд (в среднем ~17 секунд).
Для Union Read (горячий + холодный) по-прежнему нужен Flink SQL.
Хорошая новость: прямая интеграция StarRocks с Fluss уже в планах. В Roadmap StarRocks 2026 (https://github.com/StarRocks/starrocks/issues/67632) среди приоритетов это нативная поддержка Fluss как источника данных. Со стороны Fluss roadmap (https://fluss.apache.org/roadmap/) тоже включает Union Read для внешних движков, включая StarRocks. Когда это будет реализовано, StarRocks сможет читать и горячий, и холодный слой напрямую.
6. Результаты стенда
Сервер: VM, 8 vCPU (AMD EPYC), 32 ГБ ОЗУ. Docker Compose: 7 контейнеров (ZooKeeper 3.9.2, Fluss 0.8.0, Flink 1.20.1, StarRocks 4.0.6, MinIO). Сценарий: 500 станций, 100K абонентов, 2 000 CDR/сек, тиринг каждые 30 секунд. S3 (MinIO).
Flink SQL против StarRocks: сравнение
Запрос | Flink SQL (batch) | StarRocks | Ускорение |
COUNT(*) по 1.6M строк | 7-12 сек | 1.2 сек | 6-10× |
TOP-10 VIP (GROUP BY + filter + LIMIT) | 15-25 сек | 2.4 сек | 6-10× |
Тепловая карта (GROUP BY + CASE) | 15-25 сек | 3.0 сек | 5-8× |
Часовой тренд (DATE_FORMAT + GROUP BY) | 15-25 сек | 2.0 сек | 7-12× |
5 запросов подряд | 75+ сек | ~20 сек | 4× |
Работа во время стриминга | Да, но делит ресурсы | Да, независимо | - |
Свежесть данных: 2-37 сек
Ключевая метрика Streamhouse — End-to-End Freshness: время от записи события до его доступности для аналитических запросов (NOW() - MAX(source_commit_ts)). Серия из пяти замеров через StarRocks при работающих streaming-джобах, хранилище S3 (MinIO):
Замер | Строк в Paimon | Freshness (сек) |
1 | 1 647 099 | 2 |
2 | 1 647 099 | 34 |
3 | 1 647 099 | 5 |
4 | 1 647 099 | 37 |
5 | 1 647 099 | 8 |
Средняя свежесть (freshness): ~17 сек. (диапазон 2–37 сек). Разброс зависит от того, когда вы отправили запрос: сразу после тиринга – значит, данные свежие (2–5 сек), незадолго до следующего – максимальная задержка (до 37 сек).
Объём и стабильность
За несколько сессий тестирования в Paimon накопилось 1 585 699 обогащённых CDR-событий (lookup JOIN по 100K абонентов и 500 станций). Пять Flink-джобов работали стабильно без деградации на обоих хранилищах. StarRocks читал данные параллельно с работающим конвейером без конфликтов.
SQL-only конвейер
Весь конвейер от загрузки до аналитики без единой строки Java/Python:
8 SQL-команд в Flink: CREATE CATALOG + CREATE DATABASE + 3 CREATE TABLE + 3 INSERT INTO.
1 SQL-��оманда в StarRocks: CREATE EXTERNAL CATALOG.
Порог входа для инженера, знающего SQL, минимален.
Тут надо указать ограничения: стенд был на одной машине (не кластер), генератор CDR с равномерным распределением (не реальный трафик). Это доказательство архитектуры, а не нагрузочный тест!
7. Когда нужен Streamhouse
Нужен, если:
Информационные панели реального времени. Логистика, e-commerce, телеком, финансы, где данные должны обновляться в секунды.
Обнаружение мошенничества. Секунды задержки = пропущенная мошенническая транзакция.
IoT и телеметрия. Потоки с датчиков, GPS, RFID с немедленной реакцией на аномалии.
Хранилища признаков для ML. Модели требуют свежие признаки без задержки пакетно��о конвейера
Не нужен (Lakehouse достаточно), если:
Задержка 5-15 минут устраивает.
Нагрузка пакетно-ориентированная (ночные отчёты, еженедельный ETL).
Нет требований к обновлениям справочников в реальном времени.
Бюджет ограничен, а сложность Flink + Fluss + Paimon избыточна для задачи.
Что учесть перед стартом
Fluss - молодой проект (0.8.0-incubating). Мало документации, нет веб-интерфейса, отладка через журналы. Всё ещё зависит от ZooKeeper. Для production нужны дополнительные тесты отказоустойчивости.
Paimon - растущая экосистема. Поддержка уже широкая (StarRocks, Trino, Spark и другие), но еще не такая, как у Iceberg. Зато есть совместимость с Iceberg V3 - лучшее из двух миров.
8. Заключение
Streamhouse — это отличный потоковый ETL-конвейер. Flink обогащает данные в реальном времени, Fluss обеспечивает колоночное горячее хранение с субсекундной задержкой, Paimon принимает всё это в LSM-дерево с автоматической компактацией. Три компонента, SQL-only, ни строчки Java-кода — все работает.
Но без аналитического движка данные остаются в Parquet-файлах, к которым никто не может быстро обратиться. Flink SQL спроектирован для потоковых вычислений, а не для интерактивных дашбордов. Это не недостаток Flink, это просто не его задача. Данные доставлены, но не доступны для бизнес-пользователя.
StarRocks закрывает этот разрыв: одна SQL-команда для подключения к Paimon, MPP-архитектура для быстрых агрегаций, конкурентность для десятков одновременных запросов. Не замена Flink, а дополнение к нему. Каждый компонент делает то, для чего спроектирован, и не пытается заменить другие.
Полная формула, к которой мы пришли эмпирически:
Streamhouse + аналитический движок =
Flink (вычисления) + Fluss (горячий слой) + Paimon (холодный слой) + StarRocks (аналитика)
А какой стек для real-time аналитики используете вы? Если пробовали Fluss, Paimon или другие потоковые Lakehouse-решения, поделитесь опытом в комментариях. Конфигурацию Docker Compose со стендом выложу по запросу.
Хотите больше деталей по этой статье? Готовлю расширенную версию с архитектурным разбором Iceberg против Paimon, внутренностями Flink 2.0, полным SQL-кодом стенда и доработанным нашей командой для этого PoC коннектора Fluss к Flink 2.2. Подписывайтесь на Telegram-канал @starrocks_selena(https://t.me/starrocks_selena) опубликую там, как только будет готово.
