Welcome to my personal place for love, peace and happiness 🤖

Data Stack 2.0: Закат Lambda-архитектуры и восход Fluss с Lance

Data Stack 2.0: Закат Lambda-архитектуры и восход Fluss с Lance

В мире инфраструктуры данных происходит “тектонический сдвиг”, описанный в отчетах a16z.com. Индустрия отходит от сложной Lambda-архитектуры (где batch и streaming живут отдельно) к унифицированным решениям, которые называют Streamhouse.

Два ключевых игрока, меняющих правила игры в этом переходе:

  1. Apache Fluss — управляемое хранилище для потоковой обработки (Streaming Storage).
  2. Lance — формат данных нового поколения для AI и Data Lake.

1. Проблема: Почему одной Kafka больше недостаточно?

Долгое время Apache Kafka была стандартом де-факто для передачи данных. Однако, как отмечают эксперты Ververica в статье Мир без Kafka, Kafka была спроектирована как *распределенный лог*, а не как база данных.

Фундаментальные ограничения брокеров сообщений (Kafka/Pulsar) для аналитики:

  • Слабая работа с обновлениями (Updates): Kafka — это `append-only` система. Реализация `UPDATE` или `DELETE` требует использования *Compact Topics*, что не дает гарантий мгновенной консистентности и сложно в эксплуатации.
  • Медленное чтение истории: Чтобы найти запись годичной давности, вам часто нужно прочитать весь лог последовательно (Scan). Сложность операции — $O(N)$.
  • Row-based природа: Данные хранятся строками (Message bytes). Для аналитики (OLAP), где нам нужен средний чек по столбцу `price`, системе приходится распаковывать и читать *все* поля сообщения, что неэффективно.

2. Apache Fluss: Недостающее звено для Flink

Apache Fluss создан, чтобы решить проблему “разделения” между потоком и таблицей. Это нативное хранилище для Apache Flink, которое поддерживает концепцию Fluss.

Архитектурные прорывы:

  1. Гибридная модель чтения (Stream-Table Duality): Fluss позволяет читать данные и как бесконечный поток (Log), и как изменяемую таблицу с первичными ключами (Primary Key Table). Это делает реализацию CDC (Change Data Capture) тривиальной: обновления перезаписывают старые значения по ключу.
  2. Колоночная проекция (Columnar Projection): В отличие от Kafka, Fluss может отдавать аналитическому движку (Flink) только нужные колонки. Это снижает нагрузку на сеть (`I/O`) в разы.
  3. Real-Time Lookups: Fluss поддерживает точечные запросы (Point Lookup) по первичному ключу с задержкой порядка миллисекунд.
    $$Latency_{Fluss} \ll Latency_{Kafka Scan}$$ 
    Это позволяет использовать его как *Serverless State* для приложений, избавляясь от необходимости ставить рядом Redis или RocksDB.
  4. Tiered Storage в Data Lake: Fluss работает в паре с Apache Paimon (ранее Flink Table Store). Горячие данные живут в Fluss (на быстрых дисках/RAM), а по мере устаревания автоматически конвертируются в формат Lakehouse (Paimon/Parquet/ ну или Iceberg) и уходят в S3.

3. Lance: Новый стандарт для AI в Data Lake

Если Fluss отвечает за доставку и горячее состояние, то Lance меняет подход к хранению холодных данных для задач машинного обучения (ML).

Традиционный формат Parquet великолепен для аналитики (сканирование больших диапазонов), но ужасен для AI, где требуется случайный доступ (Random Access) для формирования батчей обучения.

Lance решает эти проблемы:

  • Случайный доступ:** Lance позволяет извлекать строки по индексу в ~100 раз быстрее Parquet.
  • Векторный поиск:** Это формат со встроенным векторным индексом (IVF-PQ). Вы можете хранить эмбеддинги прямо в файлах на S3 и выполнять поиск ближайших соседей (ANN) без отдельной VectorDB (вроде Pinecone или Milvus).
  • Zero-Copy версионирование:** Эффективное управление версиями датасетов без дублирования данных.

4. Сборка пазла: Как это работает вместе

Современный Streamhouse (см. примеры архитектуры]

выглядит как-то так:

Схема потока данных (Workflow):

  1. Ingestion:
    Приложения (на Go, Java, Python) пишут данные.
    • Важно:* Поскольку Fluss совместим с протоколом Kafka, можно использовать существующие Kafka-клиенты в Go-сервисах для записи в Fluss, не дожидаясь нативных библиотек. Но это пока только теория. Сходу я не нашел примеров быстро.
  1. Streaming Storage (Fluss):
    Fluss принимает данные, индексирует первичные ключи и хранит “горячее” окно (например, 24 часа).
    • Flink* выполняет `JOIN` и агрегации прямо поверх Fluss, используя `Lookup Join` (обогащение данных без сохранения большого стейта внутри Flink).
  1. Archiving & AI (Paimon/Lance):
    Исторические данные сбрасываются в S3.
    • Для классической BI-аналитики используется формат Apache Paimon или Iceberg.
    • Для ML-задач данные конвертируются или хранятся в Lance.
  1. Unified Analytics (Trino):
    Движок Trino позволяет делать SQL-запросы ко всем слоям одновременно. Аналитик пишет один `SELECT`, а Trino забирает свежие данные из Fluss, а исторические — из S3 (Lance/Parquet/iceberg).

Пример интеграции (концептуальный)

Поскольку прямого клиента Go для Fluss нет, использование в микросервисах чаще всего выглядит как работа через Kafka-протокол или HTTP-прокси, а основная логика ложится на Flink (Java/Python/ или еще чего):

// Flink SQL example: Создание таблицы, управляемой Fluss
CREATE TABLE user_behavior (
    user_id BIGINT,
    item_id BIGINT,
    action STRING,
    ts TIMESTAMP(3),
    PRIMARY KEY (user_id) NOT ENFORCED
) WITH (
    'connector' = 'fluss',
    'bootstrap.servers' = '...:9092', // Fluss совместим с Kafka-адресацией
    'table.log.consistency' = 'eventual' // Оптимизация под высокую пропускную способность
);

Надо пробовать и тестировать... все таки еще инкубационный и это только теория.

5. Выводы и рекомендации

  1. Не используйте Kafka как базу данных. Если вашей архитектуре требуются частые обновления (`UPSERT`) и точечные запросы (`Lookup`), Apache Fluss — это более подходящий инструмент в экосистеме Flink.
  2. Lance для AI. Если вы строите RAG (Retrieval-Augmented Generation) или RecSys, рассмотрите формат Lance вместо связки “Parquet + внешняя VectorDB”. Это упростит инфраструктуру.
  3. Следите за совместимостью. Интеграции Lance с Trino и Fluss с не-JVM языками (например, Go, Rust или еще чего) находятся в активной разработке. Используйте проверенные пути (Kafka Protocol для Ingestion, DataFusion/Java/Python для Querying).

Полезные ресурсы для изучения:

Follow this blog
Send
Share
Tweet
Pin