Дата публикации
ai_products

Как объединять базы данных разных команд без ETL и серверов: подход Datahike

Что появилось / что изменилось

Datahike предлагает другой способ работать с базами данных между командами:

  1. База данных как значение, а не сервис.

    • Вы не подключаетесь к живому серверу, а получаете неизменяемый снимок базы по @conn.
    • Этот снимок привязан к конкретному ID транзакции и больше не меняется.
  2. Чтение напрямую из хранилища, без отдельного сервера.

    • Все индексы лежат в хранилище (S3, файловая система, JDBC, IndexedDB через konserve).
    • Любой процесс с доступом к этому хранилищу может читать и выполнять запросы.
  3. Объединение нескольких баз в одном запросе.

    • Datalog-запросы в Datahike принимают несколько входных источников.
    • Одна команда может держать базу в одном бакете S3, другая — в другом, а аналитики объединяют их в одном выражении.
  4. Снимки без блокировок и координации.

    • Два потока, прочитавшие один и тот же снимок, всегда видят одинаковые данные.
    • Параллельные чтения не блокируют друг друга и не ждут центральный транзактор.

Цифр по производительности и стоимости авторы не приводят. Делают акцент на архитектуре: неизменяемые индексы, структурное разделение чтения и записи, отказ от отдельного слоя для чтения.

Как это работает

Datahike опирается на два ключевых принципа.

1. Неизменяемая база как значение

Идею подсказал Datomic в 2012 году: отделить процесс записи от перцепции — чтения. Один процесс пишет, все остальные читают уже сформированные значения.

В Datomic индексы лежат в хранилище, но транзактор держит в памяти последние сегменты индексов. Читатель обычно должен координироваться с транзактором, чтобы получить полный актуальный снимок.

Datahike убирает этот слой. Писатель при каждой транзакции полностью сбрасывает изменения в хранилище. Хранилище всегда содержит полноценную, авторитетную версию индексов. Чтобы прочитать базу, не нужен транзактор — достаточно доступа к стору.

2. B‑деревья со структурным sharing’ом

Индексы Datahike — это персистентные B‑деревья. Каждый узел:

  • неизменяемый;
  • хранится как пара ключ–значение в konserve;
  • может быть content‑addressed (ключ зависит от содержимого).

При новой транзакции Datahike не переписывает всё дерево. Оно создаёт новые узлы только по затронутым путям от листьев к корню и переиспользует все остальные поддеревья.

Пример из текста:

  • база содержит ~1 000 000 датомов и тысячи узлов B‑дерева;
  • транзакция добавляет 10 датомов;
  • в результате переписывается порядка десятка узлов;
  • новый корень указывает на эти новые узлы и тысячи старых.

И старое, и новое дерево — полные снимки базы, которые делят большую часть структуры. Узлы записывают один раз и больше не меняют. Это упрощает кэширование, репликацию и параллельное чтение: процессы не координируются, а просто читают одни и те же ключи из хранилища.

3. Distributed index space

Когда вы вызываете @conn, Datahike запрашивает из konserve один ключ — «голову» ветки, например :db.

Эта структура небольшая. В ней лежат:

  • корневые указатели для индексов;
  • метаданные схемы;
  • текущий ID транзакции.

Это ленивый «дескриптор». При запросе движок по мере необходимости подтягивает узлы дерева по ключам из хранилища и складывает в локальный LRU‑кэш. Повторные запросы, попадающие в те же узлы, уже не платят за I/O.

Читатели не открывают соединение с сервером, не согласуют протокол и не дергают HTTP‑API. У них есть общий «пространство индексов» в хранилище, к которому они обращаются напрямую.

Писатель публикует новый снимок в два шага:

  1. записывает новые узлы дерева;
  2. атомарно обновляет «голову» ветки.

Кто прочитает @conn после этого, увидит новый снимок. Те, кто держат старый, продолжают с ним работать — их узлы неизменяемы и не пропадут, пока на них есть ссылки.

Что это значит для вас

Для чего это хорошо:

  1. Кросс‑командная аналитика без ETL. Если одна команда держит каталог товаров в S3, а другая — остатки на складе в другом бакете, аналитики могут просто подключить обе базы в одном Datalog‑запросе. Без копирования данных, без отдельного дата‑марта.

  2. Лёгкое масштабирование чтения. Чтение не упирается в центральный сервер. Любой сервис, который может прочитать хранилище, может выполнять запросы. Это подходит для воркеров, бэкендов и локальных инструментов разработчика.

  3. Повторяемые запросы во времени. Снимки неизменяемы. Можно держать ссылку на «состояние базы на момент X» и уверенно воспроизводить отчёты, не боясь, что данные изменились между запуском скриптов.

  4. Минимальная инфраструктура. Не нужен отдельный кластер баз, API‑шлюзы и очередь сообщений только ради объединения данных. Достаточно общего доступа к S3 или другому backend’у konserve.

Где подход слабее:

  1. Высокочастотная запись. Запись каждой транзакции полностью сбрасывается в стор. Для систем с экстремальной нагрузкой на запись это может стать узким местом и потребует аккуратной настройки стораджа.

  2. Безопасность и права доступа. Концепция «любой, кто может читать хранилище, может читать базу» удобна для внутренних систем, но требует аккуратного разграничения прав: на уровне S3‑бакетов, файловой системы или JDBC.

  3. Клиентская сложность. Чтение распределено по множеству процессов. Нужен дисциплинированный подход к кэшам, управлению снимками и времени жизни ссылок.

Если вы строите аналитику и внутренние инструменты, работаете с Clojure и любите Datalog, Datahike выглядит логичным кандидатом. Для высоконагруженных транзакционных систем с жёсткими SLA по записи придётся серьёзно продумать архитектуру стораджа.

Место на рынке

Datahike идейно ближе всего к Datomic: тот же акцент на неизменяемых снимках и разделении записи и чтения. Главное отличие — в пути чтения.

  • Datomic держит в памяти у транзактора «верхушку» индексов и координирует читателей через него.
  • Datahike пишет все изменения прямиком в стор при каждой транзакции и позволяет читателям работать только со стором.

Это уменьшает инфраструктурные требования: не нужен отдельный транзактор‑как‑сервис для чтения. Но повышает требования к самому хранилищу, через konserve.

По сравнению с классическими реляционными СУБД и документ‑ориентированными хранилищами, Datahike делает ставку не на максимальную скорость единичной операции, а на архитектуру, где:

  • индексы живут в общем хранилище;
  • клиенты читают напрямую;
  • несколько снимков базы сосуществуют без блокировок и сложной координации.

Чётких числовых сравнений с PostgreSQL, MongoDB, Datomic или облачными сервисами авторы не приводят. Акцент полностью на модели данных и подходе к разделению ответственности между писателями и читателями.


Читайте также

Как объединять базы данных разных команд без ETL и серверов: подход Datahike — VogueTech | VogueTech