<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:atom="http://www.w3.org/2005/Atom">

<channel>

<title>Yuriy Gavrilov: posts tagged Database</title>
<link>https://gavrilov.info/tags/database/</link>
<description>Welcome to my personal place for love, peace and happiness 🤖 Yuiry Gavrilov</description>
<author></author>
<language>en</language>
<generator>Aegea 11.4 (v4171e)</generator>

<itunes:owner>
<itunes:name></itunes:name>
<itunes:email>yvgavrilov@gmail.com</itunes:email>
</itunes:owner>
<itunes:subtitle>Welcome to my personal place for love, peace and happiness 🤖 Yuiry Gavrilov</itunes:subtitle>
<itunes:image href="https://gavrilov.info/pictures/userpic/userpic-square@2x.jpg?1643451008" />
<itunes:explicit>no</itunes:explicit>

<item>
<title>Генерация синтетических данных с помощью SDV: от идеи до готовой таблицы в ClickHouse</title>
<guid isPermaLink="false">347</guid>
<link>https://gavrilov.info/all/generaciya-sinteticheskih-dannyh-s-pomoschyu-sdv-ot-idei-do-goto/</link>
<pubDate>Thu, 03 Sep 2026 00:49:26 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/generaciya-sinteticheskih-dannyh-s-pomoschyu-sdv-ot-idei-do-goto/</comments>
<description>
&lt;p&gt;Синтетические данные давно перестали быть просто «искусственной картинкой» — сегодня это полноценный инструмент для тестирования, разработки и даже обучения моделей машинного обучения. В этой статье я на примере реального кода покажу, как с помощью библиотеки &lt;b&gt;SDV ( &lt;a href="https://github.com/sdv-dev/sdv"&gt;Synthetic Data Vault &lt;/a&gt; )&lt;/b&gt; можно сгенерировать синтетическую копию существующей таблицы из ClickHouse, сохранив её статистические свойства и взаимосвязи.&lt;/p&gt;
&lt;p&gt;Весь код, который мы разберём, написан на Python и использует актуальную версию SDV. Спойлер: итоговый скрипт занимает меньше 80 строк, а результат — полностью готовая синтетическая таблица в вашей базе данных.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/image-240.png" width="1280" height="640" alt="" /&gt;
&lt;/div&gt;
&lt;hr /&gt;
&lt;h3&gt;Что такое SDV и зачем он нужен&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Synthetic Data Vault (SDV)&lt;/b&gt; — это Python-библиотека с открытым исходным кодом, которая стала фактическим стандартом для генерации синтетических табличных данных. Она была создана в MIT, а сегодня развивается компанией DataCebo.&lt;/p&gt;
&lt;p&gt;Главная идея SDV проста: вы даёте ей реальные данные, она обучает генеративную модель, а затем эта модель создаёт новые данные, которые &lt;b&gt;статистически неотличимы&lt;/b&gt; от оригинала, но при этом не содержат реальных записей.&lt;/p&gt;
&lt;p&gt;Ключевые возможности SDV:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Обучение на одном наборе данных&lt;/b&gt; — библиотека анализирует распределения, корреляции и зависимости между колонками.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Генерация новых записей&lt;/b&gt; — синтетические данные повторяют структуру и свойства оригинала.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Оценка качества&lt;/b&gt; — встроенные метрики показывают, насколько хорошо синтетика отражает реальные данные.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Поддержка разных типов данных&lt;/b&gt; — числовые, категориальные, даты, текстовые поля.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SDV умеет работать с одиночными таблицами, связанными таблицами и даже последовательными данными.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Какие синтезаторы предлагает SDV&lt;/h3&gt;
&lt;p&gt;SDV предлагает несколько алгоритмов (синтезаторов) на выбор. В нашем примере мы используем &lt;b&gt;`GaussianCopulaSynthesizer`&lt;/b&gt; — и вот почему.&lt;/p&gt;
&lt;table cellpadding="0" cellspacing="0" border="0" class="e2-text-table"&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Синтезатор&lt;/td&gt;
&lt;td style="text-align: center"&gt;Принцип работы&lt;/td&gt;
&lt;td style="text-align: center"&gt;Скорость&lt;/td&gt;
&lt;td style="text-align: center"&gt;Когда использовать&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;GaussianCopulaSynthesizer&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Классический статистический метод, моделирует данные через многомерное распределение&lt;/td&gt;
&lt;td style="text-align: center"&gt;Очень быстрый&lt;/td&gt;
&lt;td style="text-align: center"&gt;Рекомендуется для старта: быстрая работа, хорошее качество, прозрачность&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;CTGANSynthesizer&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Генеративно-состязательная сеть (GAN)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Медленнее&lt;/td&gt;
&lt;td style="text-align: center"&gt;Для данных со сложными зависимостями или большим количеством категориальных признаков&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;TVAESynthesizer&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Вариационный автокодировщик&lt;/td&gt;
&lt;td style="text-align: center"&gt;Средняя&lt;/td&gt;
&lt;td style="text-align: center"&gt;Альтернатива GAN, требующая больше данных для обучения&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;`GaussianCopulaSynthesizer` отлично справляется со смешанными типами данных, которые встречаются в реальных таблицах: числа, строки, даты. При этом он обучается за секунды даже на десятках тысяч строк. Именно поэтому мы выбрали его для нашего примера.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Настройка окружения&lt;/h3&gt;
&lt;p&gt;Перед запуском кода нам потребуется установить несколько пакетов. В нашем проекте мы использовали `uv` — быстрый менеджер пакетов для Python.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;uv pip install torch==2.2.2
uv pip install &amp;quot;numpy&amp;lt;2&amp;quot;
uv pip install &amp;quot;scipy&amp;lt;1.13&amp;quot;
uv pip install sdv
uv pip install clickhouse-connect&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;Важно&lt;/b&gt;: версии пакетов подобраны так, чтобы избежать конфликтов. На момент написания статьи `torch` версии 2.13.0 не имеет готовых сборок для macOS на Intel, поэтому мы используем `2.2.2`. Также важно зафиксировать `numpy&lt;2` и `scipy&lt;1.13` — более новые версии несовместимы с текущей версией `torch`.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h3&gt;Полный код генерации синтетических данных&lt;/h3&gt;
&lt;p&gt;Ниже представлен итоговый скрипт `sdv_py_v5.py`, который мы будем разбирать. Он подключается к ClickHouse, загружает реальные данные, обучает синтезатор, генерирует синтетическую копию и сохраняет результат обратно в базу.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;import clickhouse_connect
import pandas as pd
import os
import warnings
from sdv.single_table import GaussianCopulaSynthesizer
from sdv.metadata import SingleTableMetadata

# Подавляем предупреждения (включая депрекацию)
warnings.filterwarnings(&amp;quot;ignore&amp;quot;)

# Правильный импорт для однотабличных отчётов
from sdmetrics.reports.single_table import QualityReport, DiagnosticReport

# ========== НАСТРОЙКИ ==========
CLICKHOUSE_HOST = 'localhost'
CLICKHOUSE_PORT = 18123
CLICKHOUSE_USER = 'default'
CLICKHOUSE_PASSWORD = 'changeme'
CLICKHOUSE_DATABASE = 'default'

SOURCE_TABLE = 'superstore'
SYNTHETIC_TABLE = f'{SOURCE_TABLE}_synt'
LIMIT_ROWS = 10000
NUM_SYNTHETIC_ROWS = None

# ========== ПОДКЛЮЧЕНИЕ ==========
client = clickhouse_connect.get_client(
    host=CLICKHOUSE_HOST,
    port=CLICKHOUSE_PORT,
    username=CLICKHOUSE_USER,
    password=CLICKHOUSE_PASSWORD,
    database=CLICKHOUSE_DATABASE
)

# ========== ЗАГРУЗКА ==========
query = f&amp;quot;SELECT * FROM {SOURCE_TABLE} LIMIT {LIMIT_ROWS}&amp;quot;
real_df = client.query_df(query)
print(f&amp;quot;Загружено {len(real_df)} строк&amp;quot;)

# Преобразуем числовые колонки (запятая → точка)
numeric_cols = ['sales', 'discount', 'profit']
for col in numeric_cols:
    if col in real_df.columns and real_df[col].dtype == 'object':
        real_df[col] = real_df[col].str.replace(',', '.').astype(float)

# ========== МЕТАДАННЫЕ ==========
metadata = SingleTableMetadata()
metadata.detect_from_dataframe(real_df)

if os.path.exists('metadata.json'):
    os.remove('metadata.json')
metadata.save_to_json('metadata.json')
print(&amp;quot;Метаданные сохранены в metadata.json&amp;quot;)

# ========== ОБУЧЕНИЕ ==========
print(&amp;quot;Начинаем обучение синтезатора...&amp;quot;)
synthesizer = GaussianCopulaSynthesizer(metadata)
synthesizer.fit(real_df)
print(&amp;quot;Обучение завершено&amp;quot;)

# ========== ГЕНЕРАЦИЯ ==========
if NUM_SYNTHETIC_ROWS is None:
    NUM_SYNTHETIC_ROWS = len(real_df)
synthetic_df = synthesizer.sample(NUM_SYNTHETIC_ROWS)
print(f&amp;quot;Сгенерировано {len(synthetic_df)} строк&amp;quot;)

# ========== ПРЕДПРОСМОТР ==========
print(&amp;quot;\nОригинальные данные (первые 5 строк):&amp;quot;)
print(real_df.head())
print(&amp;quot;\nСинтетические данные (первые 5 строк):&amp;quot;)
print(synthetic_df.head())

# ========== ОЦЕНКА КАЧЕСТВА ==========
print(&amp;quot;\n--- Диагностика (проверка ошибок) ---&amp;quot;)
diagnostic = DiagnosticReport()
diagnostic.generate(real_df, synthetic_df, metadata.to_dict())
print(diagnostic)

print(&amp;quot;\n--- Оценка качества (статистическое сходство) ---&amp;quot;)
quality = QualityReport()
quality.generate(real_df, synthetic_df, metadata.to_dict())
print(quality)

# ========== СОХРАНЕНИЕ В CLICKHOUSE ==========
client.command(f&amp;quot;CREATE TABLE IF NOT EXISTS {SYNTHETIC_TABLE} AS {SOURCE_TABLE}&amp;quot;)
client.insert_df(SYNTHETIC_TABLE, synthetic_df)
print(f&amp;quot;\nСинтетические данные загружены в таблицу {SYNTHETIC_TABLE}&amp;quot;)

# ========== СОХРАНЕНИЕ В CSV ==========
synthetic_df.to_csv('synthetic_table.csv', index=False)
print(&amp;quot;Синтетические данные также сохранены в synthetic_table.csv&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;
&lt;h3&gt;Разбор кода по шагам&lt;/h3&gt;
&lt;h4&gt;1. Подключение к ClickHouse и загрузка данных&lt;/h4&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;client = clickhouse_connect.get_client(
    host=CLICKHOUSE_HOST,
    port=CLICKHOUSE_PORT,
    username=CLICKHOUSE_USER,
    password=CLICKHOUSE_PASSWORD,
    database=CLICKHOUSE_DATABASE
)

query = f&amp;quot;SELECT * FROM {SOURCE_TABLE} LIMIT {LIMIT_ROWS}&amp;quot;
real_df = client.query_df(query)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Мы подключаемся к ClickHouse через библиотеку `clickhouse-connect` и загружаем данные из таблицы-источника в Pandas DataFrame. Лимит в 10 000 строк — разумный компромисс между качеством обучения и скоростью. Для большинства задач этого объёма достаточно, чтобы синтезатор уловил основные закономерности.&lt;/p&gt;
&lt;h4&gt;2. Предобработка числовых данных&lt;/h4&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;numeric_cols = ['sales', 'discount', 'profit']
for col in numeric_cols:
    if col in real_df.columns and real_df[col].dtype == 'object':
        real_df[col] = real_df[col].str.replace(',', '.').astype(float)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;В нашем примере числовые колонки хранятся в ClickHouse как строки с запятой в качестве десятичного разделителя (европейский формат). Перед обучением мы преобразуем их в числа с плавающей точкой — иначе SDV не сможет корректно обработать эти данные.&lt;/p&gt;
&lt;h4&gt;3. Создание метаданных&lt;/h4&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;metadata = SingleTableMetadata()
metadata.detect_from_dataframe(real_df)
metadata.save_to_json('metadata.json')&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;SDV автоматически определяет типы каждой колонки: числовые, категориальные, даты и т.д.. Метаданные сохраняются в JSON-файл — это полезно для воспроизводимости: в следующий раз вы сможете загрузить их, а не пересоздавать заново.&lt;/p&gt;
&lt;h4&gt;4. Обучение синтезатора&lt;/h4&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;synthesizer = GaussianCopulaSynthesizer(metadata)
synthesizer.fit(real_df)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Синтезатор «изучает» ваши данные: анализирует распределения каждой колонки, корреляции между ними, паттерны пропусков. Этот процесс занимает секунды даже на 10 000 строк.&lt;/p&gt;
&lt;h4&gt;5. Генерация синтетических данных&lt;/h4&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;synthetic_df = synthesizer.sample(NUM_SYNTHETIC_ROWS)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Метод `sample()` создаёт нужное количество новых записей. В нашем случае мы генерируем столько же строк, сколько было в оригинале. При желании можно увеличить или уменьшить это число — синтезатор умеет масштабировать данные.&lt;/p&gt;
&lt;h4&gt;6. Оценка качества&lt;/h4&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;diagnostic = DiagnosticReport()
diagnostic.generate(real_df, synthetic_df, metadata.to_dict())

quality = QualityReport()
quality.generate(real_df, synthetic_df, metadata.to_dict())&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Этот этап — одна из сильных сторон SDV. Мы проверяем два аспекта:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Диагностика&lt;/b&gt; (Data Validity + Data Structure) — проверяет, что синтетические данные корректны по типам и структуре. В нашем случае — 100%.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Quality Report&lt;/b&gt; — оценивает статистическое сходство с реальными данными по двум метрикам:
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Column Shapes Score&lt;/b&gt; (90.77%) — насколько хорошо совпадают распределения отдельных колонок.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Column Pair Trends Score&lt;/b&gt; (37.71%) — насколько хорошо сохранились попарные зависимости между колонками.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Общий Score 64.24% — это нормальный результат для демонстрационного примера. Для улучшения качества можно переключиться на `CTGANSynthesizer` или увеличить объём обучающих данных.&lt;/p&gt;
&lt;h4&gt;7. Сохранение в ClickHouse&lt;/h4&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;client.command(f&amp;quot;CREATE TABLE IF NOT EXISTS {SYNTHETIC_TABLE} AS {SOURCE_TABLE}&amp;quot;)
client.insert_df(SYNTHETIC_TABLE, synthetic_df)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Финальный шаг: создаём новую таблицу с той же структурой, что и исходная, и заполняем её синтетическими данными. Всё готово — вы можете работать с синтетической копией так же, как с реальной таблицей.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Интеграция с ClickHouse: почему это важно&lt;/h3&gt;
&lt;p&gt;ClickHouse — популярная колоночная СУБД для аналитики. Генерация синтетических данных прямо в экосистему ClickHouse открывает широкие возможности:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Тестирование производительности&lt;/b&gt; — можно генерировать датасеты любого размера и проверять, как ClickHouse справляется с нагрузкой.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Разработка без доступа к продакшену&lt;/b&gt; — разработчики получают рабочую копию данных без риска утечки конфиденциальной информации.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Обучение моделей&lt;/b&gt; — синтетические данные можно использовать для предварительного обучения ML-моделей, не затрагивая реальные данные.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Альтернативный подход — использование встроенных средств ClickHouse, таких как движок `GenerateRandom`. Однако SDV даёт гораздо более качественные данные, потому что он не просто генерирует случайные значения, а воспроизводит реальные статистические паттерны.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Что дальше: улучшение качества синтеза&lt;/h3&gt;
&lt;p&gt;Если качество синтеза (особенно Column Pair Trends) вас не устраивает, вот несколько способов его улучшить:&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Увеличьте объём обучающих данных&lt;/b&gt; — вместо 10 000 строк загрузите 50 000 или 100 000.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Попробуйте CTGANSynthesizer&lt;/b&gt; — нейросетевой синтезатор лучше справляется со сложными зависимостями.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Настройте метаданные вручную&lt;/b&gt; — если автоматическое определение типов сработало неидеально, вы можете отредактировать `metadata.json` и указать типы явно.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Используйте условную генерацию&lt;/b&gt; — SDV позволяет фиксировать значения отдельных колонок и генерировать остальные с учётом этих условий.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-09-03-v-00.52.49.png" width="1360" height="708" alt="" /&gt;
&lt;/div&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-09-03-v-00.53.29.png" width="2016" height="666" alt="" /&gt;
&lt;/div&gt;
&lt;hr /&gt;
&lt;h3&gt;Заключение&lt;/h3&gt;
&lt;p&gt;Мы прошли полный путь: от установки библиотек до готовой синтетической таблицы в ClickHouse. SDV оказался мощным и при этом простым в использовании инструментом — весь процесс уместился в один скрипт на 80 строк.&lt;/p&gt;
&lt;p&gt;Главные выводы:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;SDV&lt;/b&gt; — это не просто генератор случайных данных, а интеллектуальный инструмент, который сохраняет статистическую структуру оригинала.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`GaussianCopulaSynthesizer`&lt;/b&gt; — отличная точка входа: быстрый, прозрачный, даёт хорошее качество.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Встроенная оценка качества&lt;/b&gt; позволяет объективно понять, насколько синтетика похожа на реальные данные.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Интеграция с ClickHouse&lt;/b&gt; через `clickhouse-connect` делает процесс полностью автоматизированным.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Синтетические данные открывают новые возможности для разработки, тестирования и анализа данных — без рисков, связанных с работой с реальными данными. А SDV даёт в руки инструмент, который превращает эту идею в реальность за считанные минуты.&lt;/p&gt;
&lt;p&gt;ПЫСЫ:&lt;/p&gt;
&lt;p&gt;Можно еще попробовать так: CTGANSynthesizer&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;from sdv.single_table import GaussianCopulaSynthesizer, CTGANSynthesizer&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Но надо будет дольше ждать...  и заменить тип в строке на&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;CTGANSynthesizer&lt;/code&gt;&lt;/pre&gt;&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;uv run sdv_py_v55.py
Загружено 9994 строк
Метаданные сохранены в metadata.json
Начинаем обучение синтезатора...
PerformanceAlert: Using the CTGANSynthesizer on this data is not recommended. To model this data, CTGAN will generate a large number of columns.

Original Column Name   Est # of Columns (CTGAN)
Order Date             1236
Ship Date              1334
Ship Mode              4
Customer Name          793
segment                3
Country/Region         1
region                 4
category               3
Sub-Category           17
Product Name           1849
sales                  5825
quantity               11
discount               12
profit                 7287

We recommend preprocessing discrete columns that can have many values, using 'update_transformers'. Or you may drop columns that are not necessary to model. (Exit this script using ctrl-C)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Все .. комп полетел)) 5 мин... 7 мин... 15... чем то напоминает майнинг))) .... 20... 30... пойду пожалуй спать ... утром все еще майнит, видимо надо другие параметры указывать и разобраться лучше для чего эта опция. Первая же отработала очень быстро.&lt;/p&gt;
</description>
</item>

<item>
<title>OceanBase Lakebase: Унифицированная платформа данных для AI-приложений</title>
<guid isPermaLink="false">346</guid>
<link>https://gavrilov.info/all/oceanbase-lakebase-unificirovannaya-platforma-dannyh-dlya-ai-pri/</link>
<pubDate>Wed, 02 Sep 2026 00:43:27 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/oceanbase-lakebase-unificirovannaya-platforma-dannyh-dlya-ai-pri/</comments>
<description>
&lt;h3&gt;Введение: данные есть, AI нужен контекст&lt;/h3&gt;
&lt;p&gt;Корпоративные системы данных долгое время строились вокруг четких границ: базы данных отвечали за транзакции, хранилища — за аналитику, озера данных — за хранение больших массивов сырой информации, поисковые движки индексировали документы, а векторные базы данных обеспечивали семантический поиск.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-09-02-v-00.37.49.png" width="686" height="384" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Оригинал тут: &lt;a href="https://oceanbase.medium.com/oceanbase-lakebase-a-unified-data-foundation-for-ai-native-applications-e22d5ee9fab5"&gt;OceanBase Lakebase: A Unified Data Foundation for AI-Native Applications&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Такое разделение работало, пока приложения были детерминированными, а данные — в основном структурированными. AI-приложения ведут себя иначе.&lt;/p&gt;
&lt;p&gt;Им может понадобиться профиль клиента вместе с изображениями, аудио- и видеозаписями, PDF-файлами, веб-снимками, векторными эмбеддингами и JSON-документами — и все это для одной бизнес-сущности. В многих компаниях эти данные уже существуют, но они разбросаны по разным системам с разной метаинформацией, политиками доступа и конвейерами обработки. Результат — фрагментированный стек данных, который делает AI-приложения сложными в разработке, управлении и эксплуатации.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;OceanBase Lakebase&lt;/b&gt; создан именно для решения этой проблемы.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Что такое Lakebase?&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Lakebase&lt;/b&gt; — это ядро OceanBase AI Database. Оно объединяет управление мультимодальными данными, оперативную выдачу (online serving), аналитику в реальном времени, гибридный поиск и открытые вычисления в единой архитектуре.&lt;/p&gt;
&lt;p&gt;Это не отдельное озеро данных и не традиционная база данных с надстройками AI. Это попытка переосмыслить то, как корпоративные данные должны храниться, управляться, обрабатываться и предоставляться, когда AI-приложения становятся частью производственных систем.&lt;/p&gt;
&lt;p&gt;Ключевая идея проста: структурированные бизнес-данные и мультимодальные данные должны управляться в рамках единой платформы с согласованной метаинформацией, правами доступа, управлением жизненным циклом и единым языком запросов.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-09-02-v-00.38.08.png" width="684" height="354" alt="" /&gt;
&lt;/div&gt;
&lt;hr /&gt;
&lt;h3&gt;Мультимодальные данные в одной таблице&lt;/h3&gt;
&lt;p&gt;Ключевое нововведение Lakebase — &lt;b&gt;мультимодальная таблица&lt;/b&gt;. В традиционной СУБД таблица описывает структурированные поля: идентификаторы, временные метки, суммы, статусы. В Lakebase таблица может описывать более сложные бизнес-сущности, включающие документы, изображения, аудио, видео, JSON, большие объекты, векторы и результаты работы моделей.&lt;/p&gt;
&lt;p&gt;Разные типы данных могут использовать разные форматы хранения в зависимости от размера, паттернов доступа и стоимости. Но с точки зрения пользователя, все они управляются через единую табличную модель, единую метасистему и единую систему управления.&lt;/p&gt;
&lt;p&gt;Это дает AI-приложениям более естественную модель данных. Например, обращение в службу поддержки может включать структурированные поля тикета, историю чата, записи звонков, загруженные изображения, диагностические логи и эмбеддинги. Логистическая запись — метаданные заказа, события маршрута, заметки водителя, изображения подтверждения доставки и семантические признаки. С бизнес-точки зрения это не отдельные фрагменты, а разные представления одной сущности.&lt;/p&gt;
&lt;p&gt;Lakebase упрощает хранение, поиск, управление и обработку таких сущностей как единого целого.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;AI-колонки: модели в конвейере данных&lt;/h3&gt;
&lt;p&gt;Lakebase вводит понятие &lt;b&gt;AI-колонок&lt;/b&gt; — столбцов, в которых хранятся результаты работы моделей: эмбеддинги, саммари, метки, категории или извлеченные признаки.&lt;/p&gt;
&lt;p&gt;Вместо того чтобы выгружать данные во внешний конвейер, генерировать семантические результаты и вручную записывать их обратно, команды могут приблизить обработку моделями к данным. Это дает несколько преимуществ:&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Сокращение цепочки обработки&lt;/b&gt; — меньше систем, меньше мест, где могут нарушиться согласованность данных и обработка ошибок.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Улучшение управляемости&lt;/b&gt; — эмбеддинги и метки становятся частью управляемых данных, а не скрытыми артефактами.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Надежные механизмы повторных попыток&lt;/b&gt; — в production-средах генерация эмбеддингов, саммари и извлечение признаков могут требовать пересчета при изменении исходных данных.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h3&gt;Гибридный поиск в единой платформе&lt;/h3&gt;
&lt;p&gt;AI-приложениям нужен поиск, но не один-единственный вид:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Поиск по ключевым словам&lt;/b&gt; — когда пользователи знают, что ищут.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Векторный поиск&lt;/b&gt; — когда важна семантическая близость.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Структурная фильтрация&lt;/b&gt; — когда нужно учитывать бизнес-правила, права доступа, временные диапазоны, категории продуктов или сегменты клиентов.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;В большинстве AI-стеков эти возможности разнесены по разным системам: транзакционная БД, поисковик, векторная БД и конвейер синхронизации. Для прототипов это работает, но в production возникают проблемы со свежестью данных, согласованностью прав доступа и надежностью.&lt;/p&gt;
&lt;p&gt;Lakebase объединяет структурную фильтрацию, полнотекстовый поиск и векторный поиск в едином пути запроса. Это позволяет AI-приложениям получать AI-готовый контекст из свежих операционных и мультимодальных данных без множества внешних индексов, которые могут рассинхронизироваться с источником.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Поддержка агентных нагрузок&lt;/h3&gt;
&lt;p&gt;Агенты меняют способ использования баз данных. Они могут читать, писать, искать, планировать, тестировать, изменять состояние, генерировать промежуточные результаты и многократно вызывать инструменты. При этом множество агентов могут работать параллельно, каждый со своей памятью, контекстом, правами и историей выполнения.&lt;/p&gt;
&lt;p&gt;Lakebase предоставляет основу для хранения и поиска памяти агентов, контекста сессий, бизнес-состояния и записей выполнения. Он также поддерживает изолированные среды через &lt;b&gt;ветвление (branching)&lt;/b&gt; и &lt;b&gt;песочницы (sandboxing)&lt;/b&gt;, чтобы агенты могли тестировать изменения без прямого воздействия на production-данные.&lt;/p&gt;
&lt;p&gt;Цель — не просто помочь агентам получать данные, а помочь им работать безопасно, воспроизводимо и в масштабе.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Открытое хранение и открытые вычисления&lt;/h3&gt;
&lt;p&gt;AI-нагрузки не будут выполняться в рамках одного движка. SQL остается основой для транзакционных и аналитических нагрузок. Spark широко используется для обработки больших данных. Ray и смежные фреймворки — для AI-обработки и распределенных модельных нагрузок.&lt;/p&gt;
&lt;p&gt;Lakebase поддерживает S3-совместимое объектное хранение и открытые табличные форматы, такие как &lt;b&gt;Apache Iceberg&lt;/b&gt;, позволяя вычислительным движкам (SQL, Spark, Ray) работать с общими данными и метаинформацией. Это сокращает необходимость копирования данных между системами.&lt;/p&gt;
&lt;p&gt;Открытые форматы важны, так как снижают зависимость от вендора и улучшают совместимость. Но сами по себе они не дают всех возможностей, необходимых для production-систем: оперативной выдачи, согласованности, поиска, управления и агент-ориентированных функций. Lakebase сочетает открытость с управлением на уровне базы данных и доступом в реальном времени.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Место Lakebase в OceanBase AI Database&lt;/h3&gt;
&lt;p&gt;OceanBase AI Database включает три основных слоя:&lt;/p&gt;
&lt;table cellpadding="0" cellspacing="0" border="0" class="e2-text-table"&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Продукт&lt;/td&gt;
&lt;td style="text-align: center"&gt;Роль&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Lakebase&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Ядро — управление мультимодальными данными, гибридный поиск, открытое хранение и вычисления, оперативная выдача, агент-ориентированные среды&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;DataStudio&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Рабочая среда для производства, управления и сервиса данных — помогает подготавливать, обрабатывать, моделировать и предоставлять данные для приложений, агентов и бизнес-пользователей&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;DataPilot&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Бизнес-ориентированный агент для работы с данными через естественный язык: запросы, анализ, генерация отчетов и инсайтов&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h3&gt;Российские инициативы на базе OceanBase&lt;/h3&gt;
&lt;p&gt;В России экосистема OceanBase активно развивается в рамках импортозамещения. Ключевые проекты:&lt;/p&gt;
&lt;h4&gt;1. СУБД О.К.Е.А.Н. (СберТех)&lt;/h4&gt;
&lt;p&gt;В мае 2026 года на конференции &lt;b&gt;ЦИПР-2026&lt;/b&gt; Сбер представил СУБД &lt;b&gt;О.К.Е.А.Н.&lt;/b&gt; — корпоративную систему управления базами данных, построенную на открытом коде OceanBase.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://platformv.sbertech.ru/products/rabota-s-dannymi/oceanbase"&gt;подробнее тут &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ключевые характеристики:&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Гибридная нагрузка (HTAP)&lt;/b&gt; — поддержка транзакций и аналитики в одной системе.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Горизонтальное масштабирование&lt;/b&gt; — до сотен серверов без ограничений производительности.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Надежность&lt;/b&gt; — нулевая потеря данных (RPO=0), восстановление менее чем за 8 секунд.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Экономия хранения&lt;/b&gt; — сжатие до 70–90%.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ретроспективные запросы (Flashback)&lt;/b&gt; — доступ к данным на любой момент в прошлом без резервных копий.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Поддержка SQL&lt;/b&gt; и совместимость с MySQL-протоколом.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Мультитенантность&lt;/b&gt; — изолированные логические базы в одном кластере.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Название &lt;b&gt;О.К.Е.А.Н.&lt;/b&gt; расшифровывается как:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;О&lt;/b&gt;птимизация объёмов хранения и совокупной стоимости владения&lt;/li&gt;
&lt;li&gt;&lt;b&gt;К&lt;/b&gt;ластеризация и георезервирование&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Е&lt;/b&gt;диный язык запросов SQL&lt;/li&gt;
&lt;li&gt;&lt;b&gt;А&lt;/b&gt;налитика и транзакции в одной СУБД&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Н&lt;/b&gt;адежность и неограниченная масштабируемость&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Решение включено в &lt;b&gt;Единый реестр российского ПО&lt;/b&gt; (№ 33689). Как отметил Кирилл Меньшов, старший вице-президент Сбербанка: *«Импортозамещение СУБД — один из приоритетных вопросов для крупного бизнеса сегодня»*.&lt;/p&gt;
&lt;h4&gt;2. Platform V Ocean DB&lt;/h4&gt;
&lt;p&gt;Продукт &lt;b&gt;Platform V Ocean DB&lt;/b&gt; от СберТех — это российская дистрибуция OceanBase с полной поддержкой, сертификацией и гарантией безопасности.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Итоги и тренды&lt;/h3&gt;
&lt;h4&gt;Ключевые выводы&lt;/h4&gt;
&lt;table cellpadding="0" cellspacing="0" border="0" class="e2-text-table"&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Проблема&lt;/td&gt;
&lt;td style="text-align: center"&gt;Решение Lakebase&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Данные разрознены по разным системам&lt;/td&gt;
&lt;td style="text-align: center"&gt;Единая платформа для структурированных и мультимодальных данных&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Сложность интеграции AI в data-пайплайны&lt;/td&gt;
&lt;td style="text-align: center"&gt;AI-колонки и встроенная генерация эмбеддингов&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Поиск требует нескольких систем&lt;/td&gt;
&lt;td style="text-align: center"&gt;Гибридный поиск (ключевые слова + векторы + фильтры) в одном запросе&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Агенты работают небезопасно&lt;/td&gt;
&lt;td style="text-align: center"&gt;Ветвление, песочницы, изоляция данных&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Привязка к вендорам и закрытым форматам&lt;/td&gt;
&lt;td style="text-align: center"&gt;Поддержка S3, Iceberg, SQL, Spark, Ray&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;h4&gt;Тренды&lt;/h4&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Конвергенция озер и хранилищ данных (Lakehouse)&lt;/b&gt; — стирание границ между data lakes и data warehouses.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Мультимодальные данные как норма&lt;/b&gt; — базы данных перестают быть только табличными.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Векторный поиск становится стандартом&lt;/b&gt; — неотъемлемая часть любой платформы данных.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Агент-ориентированные архитектуры&lt;/b&gt; — базы данных адаптируются под нужды ИИ-агентов.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Импортозамещение СУБД в России&lt;/b&gt; — переход на отечественные решения на базе Open Source, включая OceanBase.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h3&gt;Заключение&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;OceanBase Lakebase&lt;/b&gt; — это попытка переосмыслить корпоративную платформу данных для эпохи AI. Она объединяет мультимодальные данные, гибридный поиск, открытые вычисления и управление на уровне базы данных в единой архитектуре, чтобы предприятия могли строить AI-приложения на надежной, согласованной и масштабируемой основе.&lt;/p&gt;
&lt;p&gt;В России эта технология получает вторую жизнь в рамках инициативы &lt;b&gt;О.К.Е.А.Н.&lt;/b&gt; от СберТех, предоставляя крупному бизнесу возможность мигрировать с иностранных СУБД на российскую платформу без потери производительности и с полной поддержкой.&lt;/p&gt;
</description>
</item>

<item>
<title>QueryFlux: Universal SQL Proxy для аналитических движков</title>
<guid isPermaLink="false">337</guid>
<link>https://gavrilov.info/all/queryflux-universal-sql-proxy-dlya-analiticheskih-dvizhkov/</link>
<pubDate>Fri, 12 Jun 2026 21:15:13 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/queryflux-universal-sql-proxy-dlya-analiticheskih-dvizhkov/</comments>
<description>
&lt;blockquote&gt;
&lt;p&gt;В этой статье я расскажу, как поднять полноценную инфраструктуру для аналитических запросов, используя &lt;b&gt;QueryFlux&lt;/b&gt; — высокопроизводительный SQL-прокси на Rust, который умеет принимать запросы по разным протоколам (Trino HTTP, PostgreSQL wire, MySQL wire) и маршрутизировать их на различные бэкенды (Trino, StarRocks, DuckDB, Athena). Мы соберем стек: &lt;b&gt;Trino&lt;/b&gt; как основной движок, &lt;b&gt;Lakekeeper&lt;/b&gt; как Iceberg REST-каталог, &lt;b&gt;MinIO&lt;/b&gt; как S3-хранилище, &lt;b&gt;StarRocks&lt;/b&gt; как альтернативный MPP-движок, и наконец сам &lt;b&gt;QueryFlux&lt;/b&gt;, который предоставит единую точку входа для клиентов.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-06-12-v-20.47.49.png" width="1604" height="942" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Все конфигурации взяты из реального рабочего проекта, запущенного на macOS с Podman (но совместимы и с Docker). Детально разберем файлы, шаги запуска, решим типичные проблемы, покажем интерфейс управления и сравним QueryFlux с Trino Gateway и другими решениями.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/lakeops-org/queryflux/blob/main/examples/full-stack/docker-compose.yml"&gt;https://github.com/lakeops-org/queryflux/blob/main/examples/full-stack/docker-compose.yml&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;1. Что такое QueryFlux и зачем он нужен&lt;/h3&gt;
&lt;p&gt;Современные data-платформы часто состоят из нескольких движков: Trino для федеративных запросов, StarRocks/ClickHouse для низкой задержки, DuckDB для ad-hoc аналитики, Athena для serverless-задач. Каждый движок имеет свой wire-протокол, свой диалект SQL и свои настройки аутентификации. Клиенты вынуждены либо подключаться напрямую к каждому движку, создавая $N \times M$ интеграций, либо использовать «костыли» в коде.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;QueryFlux&lt;/b&gt; решает эту проблему, становясь единым шлюзом:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Принимает запросы по протоколам: Trino HTTP, PostgreSQL Wire, MySQL Wire, Arrow Flight SQL.&lt;/li&gt;
&lt;li&gt;Маршрутизирует запросы по правилам (протокол, заголовки, regex, Python-скрипты).&lt;/li&gt;
&lt;li&gt;Ограничивает конкурентность (через параметр `maxRunningQueries`), ведет очереди, отдает метрики в Prometheus.&lt;/li&gt;
&lt;li&gt;Поддерживает аутентификацию (OIDC, static, LDAP) и авторизацию (OpenFGA).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Документация: &lt;a href="https://queryflux.dev"&gt;queryflux.dev&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;2. Наша лабораторная конфигурация&lt;/h3&gt;
&lt;p&gt;Мы развернем следующий стек через `podman-compose` (или `docker-compose`):&lt;/p&gt;
&lt;table cellpadding="0" cellspacing="0" border="0" class="e2-text-table"&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Сервис&lt;/td&gt;
&lt;td style="text-align: center"&gt;Назначение&lt;/td&gt;
&lt;td style="text-align: center"&gt;Порт на хосте&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;trino&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Движок запросов (федерация + Iceberg)&lt;/td&gt;
&lt;td style="text-align: center"&gt;8081 (прямой доступ)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;starrocks&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Альтернативный MPP-движок&lt;/td&gt;
&lt;td style="text-align: center"&gt;9030 (MySQL протокол)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;lakekeeper&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Iceberg REST-каталог&lt;/td&gt;
&lt;td style="text-align: center"&gt;8181&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;minio&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;S3-совместимое хранилище (данные Iceberg)&lt;/td&gt;
&lt;td style="text-align: center"&gt;19000 (API), 19001 (консоль)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;postgres&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;БД метаданных Lakekeeper&lt;/td&gt;
&lt;td style="text-align: center"&gt;5433&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;queryflux&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Прокси-сервер&lt;/td&gt;
&lt;td style="text-align: right"&gt;8080 (Trino), 5434 (PG wire), 3306 (MySQL), 9000 (Admin API), 3000 (Studio UI)&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h3&gt;3. Математика планирования нагрузки (ограничение ресурсов)&lt;/h3&gt;
&lt;p&gt;Одним из важных аспектов настройки QueryFlux является управление конкурентностью (concurrency limit) через параметр `maxRunningQueries`.&lt;/p&gt;
&lt;p&gt;Если мы обозначим лимит конкурентных запросов в группе маршрутизации как N, а среднее время выполнения одного запроса на бэкенде как T (в секундах), то &lt;b&gt;теоретическая максимальная пропускная способность группы&lt;/b&gt; (Throughput, обозначается как R, в запросах в секунду) рассчитывается так:&lt;/p&gt;
&lt;p&gt;R = N /T&lt;/p&gt;
&lt;p&gt;Например, в нашем файле `config.yaml` мы задаем N = 100. Если средний аналитический запрос отрабатывает за T = 2.5 секунды, то пропускная способность нашей Trino-группы составит R = 40 запросов в секунду. Запросы сверх этого лимита попадают в очередь на стороне самого QueryFlux.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;4. Конфигурационные файлы&lt;/h3&gt;
&lt;p&gt;Создайте папку `queryflux-demo/examples/full-stack` и перейдите в нее. Ниже приведены все необходимые файлы.&lt;/p&gt;
&lt;p&gt;&lt;details&gt;&lt;br /&gt;
&lt;summary&gt;&lt;strong&gt;📄 Показать содержимое файла&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;docker-compose.yml&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(Полный стек)&lt;/strong&gt;&lt;/summary&gt;&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;name: queryflux-example-full

services:
  queryflux:
    image: ghcr.io/lakeops-org/queryflux:latest
    platform: linux/amd64
    ports:
      - &amp;quot;8080:8080&amp;quot;   # Trino HTTP через QueryFlux
      - &amp;quot;9000:9000&amp;quot;   # Admin API
      - &amp;quot;3000:3000&amp;quot;   # QueryFlux Studio
      - &amp;quot;3306:3306&amp;quot;   # MySQL wire
      - &amp;quot;5434:5434&amp;quot;   # PostgreSQL wire
    volumes:
      - ./config.yaml:/etc/queryflux/config.yaml:ro
    environment:
      RUST_LOG: ${RUST_LOG:-queryflux=info,queryflux_frontend=info}
    depends_on:
      postgres:
        condition: service_healthy
      trino:
        condition: service_healthy
      starrocks:
        condition: service_healthy
    restart: unless-stopped

  trino:
    image: trinodb/trino:latest
    platform: linux/amd64
    environment:
      CATALOG_MANAGEMENT: dynamic
    ports:
      - &amp;quot;8081:8080&amp;quot;
    healthcheck:
      test: [&amp;quot;CMD&amp;quot;, &amp;quot;curl&amp;quot;, &amp;quot;-sf&amp;quot;, &amp;quot;http://localhost:8080/v1/info&amp;quot;]
      interval: 10s
      timeout: 5s
      retries: 15
      start_period: 30s
    volumes:
      - ./trino-config/access-control.properties:/etc/trino/access-control.properties:ro

  starrocks:
    image: starrocks/allin1-ubuntu:latest
    platform: linux/amd64
    ports:
      - &amp;quot;9030:9030&amp;quot;
      - &amp;quot;8030:8030&amp;quot;
    healthcheck:
      test: [&amp;quot;CMD&amp;quot;, &amp;quot;curl&amp;quot;, &amp;quot;-sf&amp;quot;, &amp;quot;http://localhost:8030/api/health&amp;quot;]
      interval: 15s
      timeout: 10s
      retries: 20
      start_period: 60s

  postgres:
    image: postgres:16-alpine
    platform: linux/amd64
    ports:
      - &amp;quot;5433:5432&amp;quot;
    environment:
      POSTGRES_DB: queryflux
      POSTGRES_USER: queryflux
      POSTGRES_PASSWORD: queryflux
    volumes:
      - queryflux-pg:/var/lib/postgresql/data
    healthcheck:
      test: [&amp;quot;CMD-SHELL&amp;quot;, &amp;quot;pg_isready -U queryflux&amp;quot;]
      interval: 5s
      timeout: 3s
      retries: 10

  lakekeeper-db:
    image: postgres:17
    platform: linux/amd64
    environment:
      POSTGRES_PASSWORD: postgres
    healthcheck:
      test: [&amp;quot;CMD-SHELL&amp;quot;, &amp;quot;pg_isready -U postgres -p 5432 -d postgres&amp;quot;]
      interval: 2s
      timeout: 10s
      retries: 10
      start_period: 10s

  minio:
    image: minio/minio:latest
    platform: linux/amd64
    environment:
      MINIO_ROOT_USER: minio-root-user
      MINIO_ROOT_PASSWORD: minio-root-password
    command: [&amp;quot;server&amp;quot;, &amp;quot;--console-address&amp;quot;, &amp;quot;:9001&amp;quot;, &amp;quot;/data&amp;quot;]
    ports:
      - &amp;quot;19000:9000&amp;quot;
      - &amp;quot;19001:9001&amp;quot;
    healthcheck:
      test: [&amp;quot;CMD&amp;quot;, &amp;quot;curl&amp;quot;, &amp;quot;-f&amp;quot;, &amp;quot;http://localhost:9000/minio/health/ready&amp;quot;]
      interval: 2s
      timeout: 10s
      retries: 20
      start_period: 15s

  createbuckets:
    image: minio/mc:latest
    platform: linux/amd64
    depends_on:
      minio:
        condition: service_healthy
    restart: on-failure
    entrypoint: &amp;gt;
      /bin/sh -c &amp;quot;
      /usr/bin/mc alias set local http://minio:9000 minio-root-user minio-root-password;
      /usr/bin/mc mb --ignore-existing local/warehouse;
      exit 0;
      &amp;quot;

  migrate:
    image: quay.io/lakekeeper/catalog:latest-main
    platform: linux/amd64
    pull_policy: always
    environment:
      LAKEKEEPER__PG_ENCRYPTION_KEY: dev-key-not-secure
      LAKEKEEPER__PG_DATABASE_URL_READ: postgresql://postgres:postgres@lakekeeper-db:5432/postgres
      LAKEKEEPER__PG_DATABASE_URL_WRITE: postgresql://postgres:postgres@lakekeeper-db:5432/postgres
    restart: &amp;quot;no&amp;quot;
    command: [&amp;quot;migrate&amp;quot;]
    depends_on:
      lakekeeper-db:
        condition: service_healthy

  lakekeeper:
    image: quay.io/lakekeeper/catalog:latest-main
    platform: linux/amd64
    pull_policy: always
    environment:
      LAKEKEEPER__PG_ENCRYPTION_KEY: dev-key-not-secure
      LAKEKEEPER__PG_DATABASE_URL_READ: postgresql://postgres:postgres@lakekeeper-db:5432/postgres
      LAKEKEEPER__PG_DATABASE_URL_WRITE: postgresql://postgres:postgres@lakekeeper-db:5432/postgres
    command: [&amp;quot;serve&amp;quot;]
    ports:
      - &amp;quot;8181:8181&amp;quot;
    healthcheck:
      test: [&amp;quot;CMD&amp;quot;, &amp;quot;/home/nonroot/lakekeeper&amp;quot;, &amp;quot;healthcheck&amp;quot;]
      interval: 2s
      timeout: 10s
      retries: 30
      start_period: 10s
    depends_on:
      migrate:
        condition: service_completed_successfully
      lakekeeper-db:
        condition: service_healthy
      minio:
        condition: service_healthy
      createbuckets:
        condition: service_completed_successfully

  bootstrap:
    image: alpine/curl
    platform: linux/amd64
    tty: true
    stdin_open: true
    depends_on:
      lakekeeper:
        condition: service_healthy
    restart: &amp;quot;no&amp;quot;
    entrypoint: /bin/sh
    command:
      - -c
      - |
        curl -sv -X POST http://lakekeeper:8181/management/v1/bootstrap \
          -H 'Content-Type: application/json' \
          --data '{&amp;quot;accept-terms-of-use&amp;quot;: true}'
        exit 0

  initialwarehouse:
    image: alpine/curl
    platform: linux/amd64
    tty: true
    stdin_open: true
    depends_on:
      lakekeeper:
        condition: service_healthy
      bootstrap:
        condition: service_completed_successfully
    restart: &amp;quot;no&amp;quot;
    entrypoint: /bin/sh
    command:
      - -c
      - |
        curl -sv -X POST http://lakekeeper:8181/management/v1/warehouse \
          -H 'Content-Type: application/json' \
          --data @/config/create-warehouse.json
        exit 0
    volumes:
      - ./create-warehouse.json:/config/create-warehouse.json:ro

  sentinel:
    image: alpine
    platform: linux/amd64
    command: [&amp;quot;tail&amp;quot;, &amp;quot;-f&amp;quot;, &amp;quot;/dev/null&amp;quot;]
    depends_on:
      lakekeeper:
        condition: service_healthy
      initialwarehouse:
        condition: service_completed_successfully
    healthcheck:
      test: [&amp;quot;CMD&amp;quot;, &amp;quot;true&amp;quot;]
      interval: 1s
      retries: 1
      start_period: 0s

  data-loader:
    image: trinodb/trino:476
    platform: linux/amd64
    profiles: [&amp;quot;loader&amp;quot;]
    environment:
      TPCH_SCALE: ${TPCH_SCALE:-tiny}
    entrypoint: [&amp;quot;/bin/bash&amp;quot;, &amp;quot;-c&amp;quot;]
    command:
      - |
        set -euo pipefail
        sed &amp;quot;s/FROM tpch\\.tiny\\./FROM tpch.$${TPCH_SCALE}./g&amp;quot; /test-data/init.sql &amp;gt; /tmp/init.run.sql
        exec trino --server http://trino:8080 --user loader --file /tmp/init.run.sql
    volumes:
      - ../../docker/fixtures/init.docker-network.sql:/test-data/init.sql:ro
    depends_on:
      trino:
        condition: service_healthy
      sentinel:
        condition: service_healthy

  starrocks-catalog-setup:
    image: mysql:8.0
    platform: linux/amd64
    profiles: [&amp;quot;loader&amp;quot;]
    entrypoint: [&amp;quot;/bin/bash&amp;quot;, &amp;quot;-c&amp;quot;]
    command: [&amp;quot;mysql -h starrocks -P 9030 -u root --connect-timeout=30 &amp;lt; /setup/starrocks-setup.sql&amp;quot;]
    volumes:
      - ../../docker/fixtures/starrocks-setup.sql:/setup/starrocks-setup.sql:ro
    depends_on:
      starrocks:
        condition: service_healthy

volumes:
  queryflux-pg:&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/details&gt;&lt;/p&gt;
&lt;p&gt;&lt;details&gt;&lt;br /&gt;
&lt;summary&gt;&lt;strong&gt;📄 Вспомогательные конфигурационные файлы&lt;/strong&gt;&lt;/summary&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Файл `config.yaml` (настройки QueryFlux)&lt;/b&gt;:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;queryflux:
  externalAddress: http://localhost:8080
  frontends:
    trinoHttp:
      enabled: true
      port: 8080
    postgresWire:
      enabled: true
      port: 5434
  persistence:
    type: inMemory

clusters:
  trino-1:
    engine: trino
    endpoint: http://trino:8080
    enabled: true
    auth:
      type: basic
      username: trino
      password: &amp;quot;&amp;quot;

clusterGroups:
  trino-default:
    enabled: true
    maxRunningQueries: 100
    members: [trino-1]

routers:
  - type: protocolBased
    trinoHttp: trino-default
    postgresWire: trino-default

routingFallback: trino-default&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;Файл `trino-config/access-control.properties`&lt;/b&gt;:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;access-control.name=allow-all&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;Этот файл монтируется в `trino` и разрешает имперсонацию и чтение системных таблиц – иначе статистика в QueryFlux Studio не будет работать.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;b&gt;Файл `./create-warehouse.json` (инициализация warehouse Lakekeeper)&lt;/b&gt;:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;{
  &amp;quot;warehouse-name&amp;quot;: &amp;quot;test_warehouse&amp;quot;,
  &amp;quot;project-id&amp;quot;: &amp;quot;00000000-0000-0000-0000-000000000000&amp;quot;,
  &amp;quot;storage-profile&amp;quot;: {
    &amp;quot;type&amp;quot;: &amp;quot;s3&amp;quot;,
    &amp;quot;bucket&amp;quot;: &amp;quot;warehouse&amp;quot;,
    &amp;quot;endpoint&amp;quot;: &amp;quot;http://minio:9000&amp;quot;,
    &amp;quot;region&amp;quot;: &amp;quot;us-east-1&amp;quot;,
    &amp;quot;path-style-access&amp;quot;: true,
    &amp;quot;flavor&amp;quot;: &amp;quot;minio&amp;quot;,
    &amp;quot;sts-enabled&amp;quot;: false
  },
  &amp;quot;storage-credential&amp;quot;: {
    &amp;quot;type&amp;quot;: &amp;quot;s3&amp;quot;,
    &amp;quot;credential-type&amp;quot;: &amp;quot;access-key&amp;quot;,
    &amp;quot;aws-access-key-id&amp;quot;: &amp;quot;minio-root-user&amp;quot;,
    &amp;quot;aws-secret-access-key&amp;quot;: &amp;quot;minio-root-password&amp;quot;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/details&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;5. Запуск стека и проверка&lt;/h3&gt;
&lt;p&gt;Запускаем весь стек в фоновом режиме:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;cd examples/full-stack
podman-compose up -d --wait&lt;/code&gt;&lt;/pre&gt;&lt;h4&gt;5.1. Тест прямого доступа к Trino&lt;/h4&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;curl -X POST http://localhost:8081/v1/statement \
  -H 'X-Trino-User: test' \
  -d 'SELECT 1'&lt;/code&gt;&lt;/pre&gt;&lt;h4&gt;5.2. Тест через QueryFlux (PostgreSQL wire)&lt;/h4&gt;
&lt;p&gt;Подключимся через стандартный клиент `psql` к порту `5434`, который прослушивает QueryFlux:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;psql -h localhost -p 5434 -U trino -d trino&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Сначала выполним простой запрос для проверки работоспособности протокола:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;SELECT 42;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;А теперь проверим аналитический потенциал стека. Выполним тяжелый запрос к таблице `call_center` в БД Iceberg, сгенерированной по стандарту TPC-DS:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;SELECT cc_call_center_sk, cc_call_center_id, cc_rec_start_date, cc_rec_end_date, 
       cc_closed_date_sk, cc_open_date_sk, cc_name, cc_class, cc_employees, 
       cc_sq_ft, cc_hours, cc_manager, cc_mkt_id, cc_mkt_class, cc_mkt_desc, 
       cc_market_manager, cc_division, cc_division_name, cc_company, 
       cc_company_name, cc_street_number, cc_street_name, cc_street_type, 
       cc_suite_number, cc_city, cc_county, cc_state, cc_zip, cc_country, 
       cc_gmt_offset, cc_tax_percentage
FROM tpcds.sf10.call_center;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;*Скриншот успешного выполнения запроса через psql*&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-06-12-v-20.00.35.png" width="1286" height="1960" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;*Рис. 1 – Запрос `SELECT count(*) FROM system.runtime.queries` успешно выполняется через QueryFlux, статистика сразу же фиксируется и видна в Studio.*&lt;/div&gt;
&lt;/div&gt;
&lt;h4&gt;5.3. Проверка QueryFlux Studio&lt;/h4&gt;
&lt;p&gt;Откройте браузер и перейдите на `&lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;`. Логин по умолчанию: `admin` / `admin`.&lt;/p&gt;
&lt;p&gt;*Главная панель (Dashboard)*&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-06-12-v-20.00.47.png" width="1706" height="728" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;*Рис. 2 – Дашборд QueryFlux Studio: количество запросов, ошибки, средняя длительность, статус кластеров.*&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;*Список кластеров*&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-06-12-v-20.00.55.png" width="1534" height="694" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;*Рис. 3 – Страница кластеров: виден наш кластер `trino-1`, его группа `trino-default`, состояние и уровень загрузки.*&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;*Группы кластеров*&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-06-12-v-20.01.03.png" width="1704" height="892" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;*Рис. 4 – Управление группами: здесь можно задать ограничение `maxRunningQueries`, список участников и стратегии балансировки. Пока группы инициализируются из in-memory конфигурации.*&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;*Скрипты (translation fixups)*&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-06-12-v-20.01.14.png" width="1398" height="694" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;*Рис. 5 – Скрипты для трансляции диалектов SQL “на лету” (в этой демке не используются).*&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;*Guardrails (ограничения)*&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-06-12-v-20.01.34.png" width="1264" height="878" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;*Рис. 6 – Глобальные и групповые guardrails для инспекции и фильтрации SQL перед отправкой в движок.*&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;*Протоколы (frontends)*&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-06-12-v-20.01.47.png" width="1540" height="776" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;*Рис. 7 – Включённые фронтенды: Trino HTTP (8080) и PostgreSQL wire (5434).*&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;*Маршрутизация*&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-06-12-v-20.01.56.png" width="1408" height="706" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;*Рис. 8 – Правила маршрутизации: `protocolBased` направляет Trino HTTP и PostgreSQL wire в нашу группу `trino-default`.*&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;*Admin API (Swagger)*&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-06-12-v-20.02.06.png" width="1490" height="1720" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;*Рис. 9 – Документация Admin API: эндпоинты для управления кластерами, группами, конфигурациями и получения статистики.*&lt;/div&gt;
&lt;/div&gt;
&lt;hr /&gt;
&lt;h3&gt;6. Решение типичных проблем&lt;/h3&gt;
&lt;p&gt;&lt;details&gt;&lt;br /&gt;
&lt;summary&gt;&lt;strong&gt;🐞 1. Ошибка&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;internal libpod error&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;для одноразовых контейнеров на macOS&lt;/strong&gt;&lt;/summary&gt;&lt;br /&gt;
Причина: podman-compose на macOS иногда имеет баг с `tty` и `stdin_open`.&lt;br /&gt;
Решение: Параметры уже добавлены в наш `docker-compose.yml`, но если баг не ушел, выполните инициализацию Lakekeeper вручную:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;podman run --rm --network queryflux-example-full_default alpine/curl \
  -X POST http://lakekeeper:8181/management/v1/bootstrap \
  -H 'Content-Type: application/json' \
  -d '{&amp;quot;accept-terms-of-use&amp;quot;: true}'&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/details&gt;&lt;/p&gt;
&lt;p&gt;&lt;details&gt;&lt;br /&gt;
&lt;summary&gt;&lt;strong&gt;🐞 2. PostgreSQL Extended Query Protocol&lt;/strong&gt;&lt;/summary&gt;&lt;br /&gt;
QueryFlux поддерживает только &lt;b&gt;Simple Query Protocol&lt;/b&gt; (сообщение `Q`). Extended Query (Parse/Bind/Execute) не поддерживается.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;`psql` работает “из коробки”.&lt;/li&gt;
&lt;li&gt;JDBC-драйверы: добавьте параметр `prepareThreshold=0` в строку подключения, чтобы переключиться в Simple Query режим.  &lt;br /&gt;
Пример:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;jdbc:postgresql://localhost:5434/trino?prepareThreshold=0&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/details&gt;&lt;/p&gt;
&lt;p&gt;&lt;details&gt;&lt;br /&gt;
&lt;summary&gt;&lt;strong&gt;🐞 3. Ошибка&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;Access Denied: User trino cannot impersonate user queryflux-running-query-reconcile&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/strong&gt;&lt;/summary&gt;&lt;br /&gt;
Причина: Trino не разрешает имперсонацию для системных запросов QueryFlux.&lt;br /&gt;
Решение: Мы добавили файл `access-control.properties` со свойством `access-control.name=allow-all`. После этого статистика в Studio заработала (см. Рис. 1 и Рис. 2).&lt;br /&gt;
&lt;/details&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;7. Мониторинг и управление&lt;/h3&gt;
&lt;p&gt;QueryFlux предоставляет три основных интерфейса для наблюдения:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;QueryFlux Studio&lt;/b&gt; (порт 3000) – веб-интерфейс для просмотра истории запросов, управления кластерами, группами, маршрутами, скриптами и guardrails.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Admin API&lt;/b&gt; (порт 9000) – REST API для автоматизации (логин: admin/admin). Документация OpenAPI доступна на `/docs`.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Prometheus метрики&lt;/b&gt; (порт 9000/metrics) – стандартные метрики для интеграции с Grafana.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Рекомендуемая практика: для production используйте `persistence: postgres`, чтобы конфигурация групп и маршрутов сохранялась при перезапусках, а история запросов накапливалась.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;8. Сравнение QueryFlux с альтернативами&lt;/h3&gt;
&lt;h4&gt;8.1. Trino Gateway (официальный)&lt;/h4&gt;
&lt;table cellpadding="0" cellspacing="0" border="0" class="e2-text-table"&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Характеристика&lt;/td&gt;
&lt;td style="text-align: center"&gt;QueryFlux&lt;/td&gt;
&lt;td style="text-align: center"&gt;Trino Gateway&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Поддерживаемые протоколы клиента&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Trino HTTP, PostgreSQL wire, MySQL wire, Arrow Flight SQL&lt;/td&gt;
&lt;td style="text-align: center"&gt;Только Trino HTTP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Бэкенды&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Trino, DuckDB, StarRocks, Athena, ClickHouse (planned)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Только Trino&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Маршрутизация&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;По протоколу, заголовкам, тегам, regex, Python скриптам&lt;/td&gt;
&lt;td style="text-align: center"&gt;По весам, группам, header `X-Trino-Routing-Group`&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;SQL трансляция&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Да (sqlglot) – из PostgreSQL в Trino и наоборот&lt;/td&gt;
&lt;td style="text-align: center"&gt;Нет&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Конкурентность и очереди&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;`maxRunningQueries` на группу, очередь на прокси, spillover&lt;/td&gt;
&lt;td style="text-align: center"&gt;`maxConcurrentQueries` на кластер, очереди нет&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Auth/AuthZ&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;OIDC, LDAP, Static, OpenFGA&lt;/td&gt;
&lt;td style="text-align: center"&gt;Базовая поддержка `X-Trino-User`&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Метрики&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Prometheus, Grafana, Admin API, Studio&lt;/td&gt;
&lt;td style="text-align: center"&gt;Prometheus (JMX), менее развит&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;GUI управления&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Полноценный веб-интерфейс (Studio)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Отсутствует (только конфигурация API)&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&lt;b&gt;Плюсы QueryFlux:&lt;/b&gt; гетерогенность (один шлюз на разные виды движков), гибкая маршрутизация, встроенный перевод диалектов, PostgreSQL wire, наличие красивого веб-интерфейса.&lt;br /&gt;
&lt;b&gt;Минусы:&lt;/b&gt; молодой проект (версия 0.1.2), не поддерживается Extended Query Protocol для PostgreSQL, требует настройки доступа к системным таблицам Trino.&lt;/p&gt;
&lt;h4&gt;8.2. Другие альтернативы&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Trino + многокаталожность&lt;/b&gt; – простейшее решение, но требует доработки приложений для переключения на trino диалект.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Apache Linkis&lt;/b&gt; – тяжеловесный ETL-ориентированный шлюз, не подходит для лёгкой ad-hoc аналитики.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Nginx + Lua + sqlglot&lt;/b&gt; – сложно поддерживать, требует глубокой кастомной разработки.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Коммерческие решения (Starburst, Dremio)&lt;/b&gt; – дорогостоящие, но предоставляют готовую маршрутизацию, закрытый код и полноценный SLA. но 100% всего не решает так как это готовые коробки. явно захочется что-то под себя подкрутить.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;и еще много с акцентов на gateway: Hoop.dev кстати интересный и GatewayD&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GatewayD и ProxySQL: Не заменяют Trino, но отлично решают вашу задачу с логированием. GatewayD работает с PostgreSQL и может проверять запросы через Casbin, а ProxySQL предоставляет детальное логирование запросов (время, строки, IP и т.д.). Логирование — есть (аудит запросов), диалект Postgres — полный, подключение к 90 БД — сложно (нужно настраивать 90 подключений).&lt;/li&gt;
&lt;li&gt;Mammoth и JumpWire: Специализированные прокси для PostgreSQL. Первый упрощает аудит, логируя каждую команду, второй позволяет гибко настраивать политики доступа и маскировать данные. Логирование — есть, диалект Postgres — полный, подключение к 90 БД — сложно (на каждый экземпляр нужен свой прокси).&lt;/li&gt;
&lt;li&gt;Hoop.dev: Платформа для контролируемого доступа к базам данных с сильным акцентом на аудит и безопасность. Логирует все: от попыток входа до полного текста запросов и даже планов выполнения. Логирование — детальное, диалект Postgres — полный, подключение к 90 БД — сложно (требует развёртывания на каждую базу).&lt;/li&gt;
&lt;li&gt;Уже посмотрели QueryFlux: Это решение ближе всего к Trino, но работает как высокоуровневый шлюз. На входе может принимать запросы через “PostgreSQL wire”, а на выходе автоматически транслировать диалект под Trino, Clickhouse и другие системы. Логирование — ограниченное, диалект Postgres — только как входной интерфейс (запросы уходят в Trino), подключение к 90 БД — замена Trino (шлюз к 90 разным источникам).&lt;/li&gt;
&lt;li&gt;SQL Gateway (CData): Позволяет представить любые ODBC-источники как виртуальную PostgreSQL или SQL Server базу. Логирование — только общее, диалект Postgres — виртуальный (эмуляция), подключение к 90 БД — сложно (настройка ODBC).&lt;/li&gt;
&lt;li&gt;Cloud Service Gateways (Infisical и др.): Специализированные облачные решения. Обещают централизованный доступ и аудит, но их возможности нативных диалектов сильно привязаны к конкретному провайдеру.&lt;/li&gt;
&lt;li&gt;Native PostgreSQL Gateways: Как сборник технологий (например, PgCat), из которых можно построить своё решение. Позволяет гибко настраивать подключения и логи, но требует ручной сборки и высокой квалификации.&lt;br /&gt;
Интеграция с Keycloak: К сожалению, прямой интеграции с Keycloak для аутентификации SQL-запросов практически нет. Keycloak используется для аутентификации доступа к веб-интерфейсам административных консолей, но не для самих SQL-клиентов. Исключение — GatewayD, который, хотя и не интегрируется с Keycloak, позволяет реализовать схожую логику через Casbin.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;Вывод:&lt;/b&gt; QueryFlux идеален, если у вас уже есть несколько движков и вы хотите дать единую точку входа для бизнес-пользователей и аналитиков (особенно тех, кто привык к `psql`). Для production, где критична поддержка prepare-statements, стоит использовать Trino JDBC напрямую или использовать дополнительный прокси (например, `trino-pg-gateway`).&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;9. Итоги и рекомендации&lt;/h3&gt;
&lt;p&gt;Мы успешно запустили полноценный аналитический стек с Lakekeeper (Iceberg), Trino и StarRocks, а QueryFlux обеспечил единый вход через HTTP и PostgreSQL wire. Ключевые достижения:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ QueryFlux принимает Trino HTTP и PostgreSQL wire запросы, направляя их в Trino.&lt;/li&gt;
&lt;li&gt;✅ Клиент `psql` выполняет сложные `SELECT`-запросы к Iceberg таблицам (даже TPC-DS) через порт 5434.&lt;/li&gt;
&lt;li&gt;✅ Статистика в Studio отображается корректно.&lt;/li&gt;
&lt;li&gt;✅ Маршрутизация по протоколу (`protocolBased`) работает как задумано.&lt;/li&gt;
&lt;li&gt;✅ Веб-интерфейс Studio даёт полный контроль над кластерами, группами, маршрутами и скриптами.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;Рекомендации для production:&lt;/b&gt;&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Замените `persistence: inMemory` на `persistence: postgres` и настройте репликацию БД конфигурации (чтобы не терять историю и настройки).&lt;/li&gt;
&lt;li&gt;Включите аутентификацию OIDC (Keycloak) и авторизацию OpenFGA для разграничения доступа к группам кластеров.&lt;/li&gt;
&lt;li&gt;Рассчитайте `maxRunningQueries` по формуле N = R \times T, исходя из планируемой нагрузки и SLA.&lt;/li&gt;
&lt;li&gt;Для PostgreSQL-клиентов с GUI (DataGrip/DBeaver) используйте параметр `prepareThreshold=0` (через JDBC) или переключитесь на официальный Trino JDBC драйвер.&lt;/li&gt;
&lt;li&gt;Настройте сбор метрик в Prometheus и дашборды Grafana для мониторинга длины очередей и задержек.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;Заключение:&lt;/b&gt; QueryFlux — очень перспективный и многообещающий инструмент для построения унифицированного доступа к аналитическим движкам. Несмотря на молодость, он уже пригоден для некоторых сценариев, особенно если вы готовы ограничиться simple query protocol при использовании PostgreSQL wire. В связке с Iceberg-каталогами и объектным хранилищем он образует мощную open-source альтернативу дорогим коммерческим решениям.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
</item>

<item>
<title>Рейтинг Open Source Графовых СУБД для AdTech</title>
<guid isPermaLink="false">305</guid>
<link>https://gavrilov.info/all/reyting-open-source-grafovyh-subd-dlya-adtech/</link>
<pubDate>Sun, 14 Dec 2025 14:24:45 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/reyting-open-source-grafovyh-subd-dlya-adtech/</comments>
<description>
&lt;p&gt;Для задач &lt;b&gt;AdTech сегментации&lt;/b&gt; (профилирование пользователей, identity resolution, поиск look-alike аудиторий) набор требований к графовой базе данных специфичен: нужна высокая скорость операций чтения/записи (real-time bidding/serving) и горизонтальная масштабируемость (миллиарды событий и связей).&lt;/p&gt;
&lt;p&gt;Учитывая популярность текущего стека (&lt;b&gt;ClickHouse, Trino, Qdrant&lt;/b&gt;), идеальная графовая база должна уметь интегрироваться в аналитический контур (через Trino или прямые коннекторы) и дополнять ClickHouse (который хранит логи событий), взяв на себя хранение топологии связей.&lt;/p&gt;
&lt;p&gt;Ниже представлен небольшой обзор и рейтинг Open Source решений на 2024-2025 год с фокусом на масштабируемость.&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;Рейтинг Open Source Графовых СУБД для AdTech&lt;/h4&gt;
&lt;p&gt;Разделим 12 решений на 3 эшелона по пригодности для высоконагруженной сегментации.&lt;/p&gt;
&lt;h5&gt;1 эшелон: Лидеры производительности и масштабирования (Native Distributed)&lt;/h5&gt;
&lt;p&gt;Эти базы изначально создавались для кластеров и больших объемов данных.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;1. NebulaGraph&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Тип:&lt;/b&gt; Native Distributed Graph Database.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Язык запросов:&lt;/b&gt; nGQL (SQL-подобный).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Архитектура:&lt;/b&gt; Разделение Compute (GraphD) и Storage (StorageD). Shared-nothing.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Плюсы для вас:&lt;/b&gt; Это топ-1 выбор для AdTech масштаба Tencent или Meituan. Спокойно переваривает сотни миллиардов вершин и триллионы ребер. Обеспечивает миллисекундный отклик при обходе графа (hops) на большую глубину.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Минусы:&lt;/b&gt; Более крутая кривая обучения, чем у Neo4j. Сообщество меньше, но растет.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Связь со стеком:&lt;/b&gt; Отлично дополнит ClickHouse (CH хранит атрибуты, Nebula — связи). Есть коннекторы для Spark/Flink. А через Spark можно дойти до Trino.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;2. Dgraph&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Тип:&lt;/b&gt; Native Distributed Graph.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Язык запросов:&lt;/b&gt; GraphQL (модифицированный DQL).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Архитектура:&lt;/b&gt; Распределенная, использует BadgerDB (KV store) под капотом. Поддерживает шардинг и репликацию “из коробки” в open source версии.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Плюсы:&lt;/b&gt; Горизонтальное масштабирование. Очень удобна для фронтенд-разработчиков благодаря GraphQL. Высокая пропускная способность.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Минусы:&lt;/b&gt; Специфичный язык запросов, если вы привыкли к SQL/Cypher. В последние годы темпы разработки ядра немного снизились относительно конкурентов.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;3. Memgraph&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Тип:&lt;/b&gt; In-Memory Graph Database (написана на C++).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Язык запросов:&lt;/b&gt; Cypher (совместим с Neo4j).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Архитектура:&lt;/b&gt; Работает в оперативной памяти (с возможностью сброса на диск).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Плюсы:&lt;/b&gt; &lt;b&gt;Самая быстрая&lt;/b&gt; для задач реального времени (вычисление фичей для RTB). Полная совместимость с экосистемой Neo4j (драйверы, протокол Bolt). Поддерживает Python/Rust процедуры. Отличная работа с Streaming данными (Kafka).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Минусы:&lt;/b&gt; Ограничена объемом RAM (хотя есть disk-spill, это снижает скорость).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Связь со стеком:&lt;/b&gt; Отлично стыкуется с моделями AI (Qdrant), так как позиционируется для “Graph AI”.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;2 эшелон: Классика и Универсалы&lt;/h5&gt;
&lt;p&gt;&lt;b&gt;4. Neo4j (Community Edition)&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Тип:&lt;/b&gt; Native Graph.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Язык:&lt;/b&gt; Cypher (стандарт индустрии).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Плюсы:&lt;/b&gt; Огромное сообщество, лучшая документация, куча плагинов (APOC).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Главный минус для AdTech:&lt;/b&gt; Open Source версия (Community) ограничена &lt;b&gt;одним узлом&lt;/b&gt;. Нет встроенного кластеризации и шардинга (доступно только в Enterprise за большие деньги). Для “технического задела на вырост” в Open Source варианте — это бутылочное горлышко.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;5. ArangoDB&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Тип:&lt;/b&gt; Multi-model (Graph, Document, Key/Value).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Язык:&lt;/b&gt; AQL (похож на SQL).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Плюсы:&lt;/b&gt; Гибкость. Можно хранить сложные JSON-документы (как в Mongo) и связывать их.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Минусы:&lt;/b&gt; При глубоких обходах графа (“друзья друзей друзей”) проигрывает специализированным Native Graph базам по скорости. Это компромиссное решение.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;6. JanusGraph&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Тип:&lt;/b&gt; Layered Graph Database.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Плюсы:&lt;/b&gt; Работает поверх мощных бэкендов (Cassandra, HBase, ScyllaDB) и использует Elasticsearch для индексации. Масштабируемость ограничена только бэкендом.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Минусы:&lt;/b&gt; Очень “тяжелая” инфраструктура (JVM based). Сложна в настройке и эксплуатации. Медленнее на простых запросах из-за сетевых хопов между слоями. Часто считается “устаревающей” архитектурой по сравнению с Nebula/Dgraph.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;7. Apache AGE (PostgreSQL Extension)&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Тип:&lt;/b&gt; Extension.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Суть:&lt;/b&gt; Превращает PostgreSQL в графовую БД с поддержкой Cypher.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Плюсы:&lt;/b&gt; Если вы знаете Postgres, вы знаете AGE. Не нужно новой инфраструктуры.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Минусы:&lt;/b&gt; Производительность ограничена движком Postgres. Сложно масштабировать горизонтально на запись (проблема шардинга PG).&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;3 эшелон: Нишевые и Новые игроки&lt;/h5&gt;
&lt;p&gt;&lt;b&gt;8. HugeGraph&lt;/b&gt; (Baidu) — аналог JanusGraph, популярен в Китае, очень мощный, но документация местами страдает.&lt;br /&gt;
&lt;b&gt;9. OrientDB&lt;/b&gt; — мультимодельная, была популярна, но сейчас развитие замедлилось.&lt;br /&gt;
&lt;b&gt;10. FalkorDB&lt;/b&gt; — форк закрывшегося RedisGraph (Redis module). Очень быстрый, использует разреженные матрицы. Интересен, если уже есть Redis.&lt;br /&gt;
&lt;b&gt;11. Cayley&lt;/b&gt; — написана на Go (Google), простая, работает с триплетами (Linked Data), но для сложной AdTech логики может не хватить функционала.&lt;br /&gt;
&lt;b&gt;12. TerminusDB&lt;/b&gt; — интересная база с концепцией “Git для данных”, но специфична для версионирования знаний, а не высоконагруженной сегментации.&lt;/p&gt;
&lt;h4&gt;Сравнительная таблица (ТОП-7 для выбора)&lt;/h4&gt;
&lt;table cellpadding="0" cellspacing="0" border="0" class="e2-text-table"&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;СУБД&lt;/td&gt;
&lt;td style="text-align: center"&gt;Язык запросов&lt;/td&gt;
&lt;td style="text-align: center"&gt;Архитектура&lt;/td&gt;
&lt;td style="text-align: center"&gt;Масштабирование (Open Source)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Скорость (Read/Traverse)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Сложность эксплуатации&lt;/td&gt;
&lt;td style="text-align: center"&gt;Идеально для&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;NebulaGraph&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;nGQL (SQL-like)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Distributed Native&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Отличное&lt;/b&gt; (Sharding+Replication)&lt;/td&gt;
&lt;td style="text-align: center"&gt;🔥 Очень высокая&lt;/td&gt;
&lt;td style="text-align: center"&gt;Средняя/Высокая&lt;/td&gt;
&lt;td style="text-align: center"&gt;Big Data, AdTech, Fraud&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Memgraph&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Cypher&lt;/td&gt;
&lt;td style="text-align: center"&gt;In-Memory (C++)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Вертикальное / Репликация&lt;/td&gt;
&lt;td style="text-align: center"&gt;🚀 &lt;b&gt;Топ-1 (Low Latency)&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Низкая (как Docker)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Real-time features, Streaming&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Dgraph&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;GraphQL&lt;/td&gt;
&lt;td style="text-align: center"&gt;Distributed Native&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Отличное&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Высокая&lt;/td&gt;
&lt;td style="text-align: center"&gt;Средняя&lt;/td&gt;
&lt;td style="text-align: center"&gt;App Backend, 360 Customer View&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Neo4j (CE)&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Cypher&lt;/td&gt;
&lt;td style="text-align: center"&gt;Native&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Нет&lt;/b&gt; (только 1 нода)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Высокая (локально)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Низкая&lt;/td&gt;
&lt;td style="text-align: center"&gt;R&amp;D, малые проекты&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;ArangoDB&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;AQL&lt;/td&gt;
&lt;td style="text-align: center"&gt;Multi-model&lt;/td&gt;
&lt;td style="text-align: center"&gt;Хорошее (Cluster mode)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Средняя&lt;/td&gt;
&lt;td style="text-align: center"&gt;Средняя&lt;/td&gt;
&lt;td style="text-align: center"&gt;Гибридные данные (Docs+Graph)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;JanusGraph&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Gremlin&lt;/td&gt;
&lt;td style="text-align: center"&gt;Layered (over NoSQL)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Бесконечное (зависит от Backend)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Низкая/Средняя&lt;/td&gt;
&lt;td style="text-align: center"&gt;☠️ Высокая&lt;/td&gt;
&lt;td style="text-align: center"&gt;Если уже есть HBase/Cassandra&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Apache AGE&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Cypher&lt;/td&gt;
&lt;td style="text-align: center"&gt;Postgres Ext&lt;/td&gt;
&lt;td style="text-align: center"&gt;Только Read Replicas&lt;/td&gt;
&lt;td style="text-align: center"&gt;Средняя&lt;/td&gt;
&lt;td style="text-align: center"&gt;Низкая (если знают PG)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Гибрид SQL + Graph&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;h4&gt;Интеграция с текущим стеком (Qdrant, Trino или ClickHouse)&lt;/h4&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Qdrant + Graph DB = GraphRAG / Semantic Search:&lt;/b&gt;
&lt;ul&gt;
  &lt;li&gt;Сегментация пользователей часто требует поиска не только по связям (“кто кликал то же, что и я”), но и по похожести векторов (“чей профиль похож на мой”).&lt;/li&gt;
  &lt;li&gt;Memgraph&lt;b&gt; и **Neo4j&lt;/b&gt; имеют встроенные модули для работы с векторами, но так как у вас уже есть &lt;b&gt;Qdrant&lt;/b&gt;, вам нужна база, которая *не пытается заменить Qdrant*, а позволяет хранить ID векторов в узлах графа.&lt;/li&gt;
  &lt;li&gt;NebulaGraph** позволяет хранить embedding в свойствах узла, но поиск лучше делегировать Qdrant.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;b&gt;Trino:&lt;/b&gt;
&lt;ul&gt;
  &lt;li&gt;Вам захочется делать SQL-запросы сразу к ClickHouse (события) и Графу (профиль).&lt;/li&gt;
  &lt;li&gt;У &lt;b&gt;Neo4j&lt;/b&gt; и &lt;b&gt;NebulaGraph&lt;/b&gt; есть коннекторы, позволяющие Trino (через JDBC или нативные коннекторы) запрашивать данные. Это мощнейшая связка для аналитиков. Отдельно нативного конектора к Trino пока не найти, но скоро может появится поддержка iceberg &lt;a href="https://github.com/vesoft-inc/nebula/discussions/5902"&gt;https://github.com/vesoft-inc/nebula/discussions/5902&lt;/a&gt; или пока можно использоваться связку через Spark.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="3"&gt;
&lt;li&gt;&lt;b&gt;ClickHouse:&lt;/b&gt;
&lt;ul&gt;
  &lt;li&gt;Паттерн: ClickHouse хранит “сырые” логи (миллиарды строк). Агрегаты и связи (User Graph) пересчитываются и заливаются в Графовую БД для быстрого lookup.&lt;/li&gt;
  &lt;li&gt;NebulaGraph** имеет Exchange (инструмент на основе Spark) для массовой заливки данных из Warehouse.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h4&gt;Итоговая рекомендация&lt;/h4&gt;
&lt;p&gt;Учитывая, что вы хотите &lt;b&gt;Open Source&lt;/b&gt; и вам нужен &lt;b&gt;технический задел (масштабирование)&lt;/b&gt; для AdTech:&lt;/p&gt;
&lt;h5&gt;🏆 Выбор №1: NebulaGraph&lt;/h5&gt;
&lt;p&gt;Это наиболее близкий аналог “ClickHouse в мире графов”.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Почему:** Он создан для хранения миллиардов вершин (пользователей/устройств) и работы в кластере. У него shared-nothing архитектура, которая необходима для роста. Язык nGQL будет понятен вашим аналитикам, знающим SQL (ClickHouse/Trino).&lt;/li&gt;
&lt;li&gt;Для AdTech:** Идеально решает проблемы *Identity Resolution* (склеивание cookie, device_id, user_id и других атрибутов в единый граф) на больших объемах.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;🥈 Выбор №2: Memgraph&lt;/h5&gt;
&lt;p&gt;Если ваши графы помещаются в память (сотни миллионов узлов, но не десятки миллиардов) и критична задержка (latency) менее 10 мс для *real-time* принятия решений.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Почему:** Он безумно быстр. Он совместим с Cypher (легко нанимать людей или переезжать с Neo4j). Написан на C++, очень эффективен.&lt;/li&gt;
&lt;li&gt;Интеграция:** Идеально, если вы планируете стримить данные из Kafka, обновлять граф и сразу выдавать сегменты.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;🥉 Выбор №3: Apache AGE (или ArangoDB)&lt;/h5&gt;
&lt;p&gt;Только если объем графа невелик, и вы хотите минимизировать зоопарк технологий, оставаясь в рамках “почти SQL” решений. Но для серьезного AdTech они не рекомендуется как *основное* хранилище графа пользователей.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Совет:&lt;/b&gt; Начните пилот (PoC) с &lt;b&gt;NebulaGraph&lt;/b&gt;. Попробуйте загрузить туда выгрузку из ClickHouse и сравнить скорость выполнения запросов “найти всех пользователей, связанных через устройство X на глубину 3 шага” с тем, как это делается сейчас (вероятно, через JOINs в реляционке или CH). Если сложность эксплуатации Nebula покажется высокой, можно посмотреть в сторону &lt;b&gt;Memgraph&lt;/b&gt; как более легкой альтернативы и применять их не на одном большом графе например, а на нескольких малых в реальном времени, а готовые расчеты уже хранить в привычных местах.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Еще можно почитать:&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bigdataschool.ru/blog/memgraph-vs-neo4j/"&gt;Сравнение Memgraph и Neo4j bigdataschool.ru&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bigdataschool.ru/blog/neo4j-vs-tigergraph-what-to-choose.html"&gt;Сравнение Neo4j и TigerGraph (для понимания коммерческого рынка bigdataschool.ru&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wiki.merionet.ru/articles/10-lucsix-resenii-dlia-raboty-s-grafovymi-bazami-dannyx"&gt;Обзор графовых БД wiki.merionet.ru&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Вот еще мысль и про языки немного. Если проект большой с единым графом для разных нужд, то NebulaGraph выглядит лучшим решением, но архитектурно можно выбрать много средних и малых графов. Для второго подхода хорошо Memgraph с его языком Cypher&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;1. Семейство Cypher (OpenCypher / ISO GQL)&lt;/h4&gt;
&lt;p&gt;&lt;b&gt;Базы:&lt;/b&gt; *Neo4j, Memgraph, FalkorDB, Apache AGE.*&lt;/p&gt;
&lt;p&gt;Cypher — это «SQL для графов». Это декларативный язык, использующий ASCII-арт для визуализации связей в коде (например, `(User)-[:CLICKS]-&gt;(Ad)`).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Функциональность:&lt;/b&gt; Очень богатая. Поддерживает сложные паттерны (Pattern Matching), агрегации, пути переменной длины. В апреле 2024 года ISO утвердила стандарт &lt;b&gt;GQL&lt;/b&gt; (Graph Query Language), который во многом основан на Cypher.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Плюсы:&lt;/b&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Интуитивность:&lt;/b&gt; Код читается как предложение на английском. Самая низкая кривая входа.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Экосистема:&lt;/b&gt; Стандарт де-факто. Если вы знаете Cypher, вы можете переключаться между Neo4j, Memgraph и AGE без переобучения.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Выразительность:&lt;/b&gt; Идеален для глубокой аналитики и поиска сложных паттернов (Fraud Detection).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Минусы:&lt;/b&gt;
&lt;ul&gt;
  &lt;li&gt;Изначально создавался для одноузловых систем. В распределенных системах (шардинг) некоторые конструкции Cypher могут быть сложны для оптимизации движком.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Оценка для стека:&lt;/b&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Memgraph/Neo4j:&lt;/b&gt; Работает идеально.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Apache AGE:&lt;/b&gt; Cypher оборачивается внутри SQL запросов Postgres, что немного громоздко, но функционально.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;FalkorDB:&lt;/b&gt; Реализует подмножество Cypher, очень быстро благодаря Redis, но функционал беднее, чем у Neo4j.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2. Семейство Gremlin (Apache TinkerPop)&lt;/h4&gt;
&lt;p&gt;&lt;b&gt;Базы:&lt;/b&gt; *JanusGraph, HugeGraph, OrientDB (частично), Azure CosmosDB.*&lt;/p&gt;
&lt;p&gt;Gremlin — это императивный язык обхода графа (Traversals). Вы пишете не «что найти» (как в SQL/Cypher), а «куда идти» шаг за шагом.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Функциональность:&lt;/b&gt; Тьюринговская полнота. Можно написать алгоритм любой сложности прямо внутри запроса. Это скорее язык программирования потоков данных, чем язык запросов.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Плюсы:&lt;/b&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Контроль:&lt;/b&gt; Вы точно указываете базе, как обходить граф. Это важно для сверхбольших графов (как в JanusGraph/HugeGraph), где неверный план запроса может “положить” кластер.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Абстракция:&lt;/b&gt; Работает поверх любой БД, поддерживающей TinkerPop.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Минусы:&lt;/b&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Сложность:&lt;/b&gt; Кривая обучения очень крутая. Код получается вербозным и сложным для отладки («write once, read never»).&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Устаревание:&lt;/b&gt; С появлением стандарта ISO GQL популярность Gremlin падает. Для новых проектов в 2025 году его выбирают редко, если только не привязаны к JanusGraph.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Пример AdTech:&lt;/b&gt; «Найти всех пользователей, кликнувших на этот баннер» на Gremlin будет длинной цепочкой вызовов методов (`g.V().has(‘Banner’...).out(‘CLICKS’)...`).&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;3. nGQL (NebulaGraph Query Language)&lt;/h4&gt;
&lt;p&gt;&lt;b&gt;Базы:&lt;/b&gt; *NebulaGraph.*&lt;/p&gt;
&lt;p&gt;Собственный язык Nebula, который синтаксически мимикрирует под SQL, но логически работает с графами.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Функциональность:&lt;/b&gt; Заточена под распределенный Massive Parallel Processing (MPP).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Плюсы:&lt;/b&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;SQL-подход:&lt;/b&gt; Разработчикам, привыкшим к MySQL/ClickHouse, синтаксис `GO FROM ... OVER ...` будет понятнее, чем Gremlin.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Скорость:&lt;/b&gt; Спроектирован так, чтобы не позволять писать «плохие» запросы, которые убивают распределенный кластер. Вынуждает думать о том, где лежат данные (VID).&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Пайпы:&lt;/b&gt; Удобный синтаксис передачи результата одного шага в другой через `|` (как в Bash).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Минусы:&lt;/b&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Vendor Lock-in:&lt;/b&gt; Это не стандарт. Переехать с Nebula на другую базу потребует переписывания всех запросов.&lt;/li&gt;
  &lt;li&gt;Не поддерживает полную гибкость Pattern Matching, как Cypher (хотя добавили поддержку `MATCH`, она менее производительна, чем нативный `GO`).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;4. DQL (ранее GraphQL+-)&lt;/h4&gt;
&lt;p&gt;&lt;b&gt;Базы:&lt;/b&gt; *Dgraph.*&lt;/p&gt;
&lt;p&gt;Это модифицированный GraphQL.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Функциональность:&lt;/b&gt; Идеальна для API. Вы запрашиваете данные в формате JSON-дерева, и база возвращает JSON.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Плюсы:&lt;/b&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Frontend-first:&lt;/b&gt; Фронтендерам не нужен бэкенд-прослойка, они могут (теоретически) ходить в базу почти напрямую.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Работа с атрибутами:&lt;/b&gt; Поскольку Dgraph — это по сути распределенный Key-Value, DQL очень быстро достает атрибуты нод.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Минусы:&lt;/b&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Слабая аналитика:&lt;/b&gt; Графовые алгоритмы и сложные обходы (traversals) на DQL писать сложнее и менее эффективно, чем на Cypher/nGQL. Это язык выборки данных, а не язык аналитики графов.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;5. AQL (ArangoDB Query Language)&lt;/h4&gt;
&lt;p&gt;&lt;b&gt;Базы:&lt;/b&gt; *ArangoDB.*&lt;/p&gt;
&lt;p&gt;Гибридный язык, объединяющий возможности SQL (JOINs), работы с JSON (как в Mongo) и графовых обходов.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Функциональность:&lt;/b&gt; Одна из самых мощных среди “универсалов”. Позволяет в одном запросе сделать JOIN трех коллекций, отфильтровать JSON и пройтись по графу друзей.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Плюсы:&lt;/b&gt; Гибкость.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Минусы:&lt;/b&gt; Синтаксис `FOR u IN users FILTER ...` специфичен и многословен. Для чистых графовых задач (deep hopping) он медленнее нативных решений [ArangoDB vs Native Graph].&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;6. Другие / Устаревающие&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;OrientDB (SQL-extended):&lt;/b&gt; Пытались расширить SQL для графов. Сейчас проект стагнирует, язык считается тупиковой ветвью эволюции по сравнению с Cypher/GQL.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;SQL Graph (MS SQL / PG SQL):&lt;/b&gt; В [статье про SQL Server](&lt;a href="https://learn.microsoft.com/ru-ru/sql/relational-databases/graphs/sql-graph-sample?view=sql-server-ver17)"&gt;https://learn.microsoft.com/ru-ru/sql/relational-databases/graphs/sql-graph-sample?view=sql-server-ver17)&lt;/a&gt; показан синтаксис `MATCH`, который Microsoft внедрила в T-SQL. Это попытка “догнать” Cypher, оставаясь в рамках реляционной модели. Удобно, если вы намертво привязаны к MS SQL, но неудобно для сложной аналитики.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Cayley (Gizmo/MQL):&lt;/b&gt; Очень нишевый язык на базе Go или JS. Для AdTech продакшена слишком экзотичен.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h4&gt;Сводная таблица сравнения&lt;/h4&gt;
&lt;table cellpadding="0" cellspacing="0" border="0" class="e2-text-table"&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Язык&lt;/td&gt;
&lt;td style="text-align: center"&gt;Базы данных&lt;/td&gt;
&lt;td style="text-align: center"&gt;Порог входа&lt;/td&gt;
&lt;td style="text-align: center"&gt;Для AdTech/High-load&lt;/td&gt;
&lt;td style="text-align: center"&gt;Стандартность (2025)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Примечание&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;nGQL&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;NebulaGraph&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Средний&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Идеально&lt;/b&gt; (Tencent scale)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Низкая (Vendor specific)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Топ для сотен млрд связей и кластерной архитектуры.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Cypher&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Memgraph&lt;/b&gt;, Neo4j, AGE&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Низкий&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Хорошо (Memgraph) / Средне (Neo4j)&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Высокая&lt;/b&gt; (основа ISO GQL)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Самый удобный для аналитиков и Data Science.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;DQL&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Dgraph&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Низкий (для Web-dev)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Хорошо (для OLTP)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Низкая&lt;/td&gt;
&lt;td style="text-align: center"&gt;Лучший выбор, если граф — это бэкенд для UI.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: right"&gt;&lt;b&gt;Gremlin&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;JanusGraph, HugeGraph&lt;/td&gt;
&lt;td style="text-align: center"&gt;Высокий&lt;/td&gt;
&lt;td style="text-align: center"&gt;Отлично (если настроить)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Падает (Legacy)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Слишком сложен в поддержке, проигрывает современным языкам.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;AQL&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;ArangoDB&lt;/td&gt;
&lt;td style="text-align: center"&gt;Средний&lt;/td&gt;
&lt;td style="text-align: center"&gt;Средне&lt;/td&gt;
&lt;td style="text-align: center"&gt;Низкая&lt;/td&gt;
&lt;td style="text-align: center"&gt;Хорош, если нужна “Document Store + Graph” в одном.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;h4&gt;Итоговая рекомендация&lt;/h4&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Если приоритет — производительность на масштабе (AdTech, сегментация 100M+ пользователей):&lt;/b&gt;  &lt;br /&gt;
Вам нужен &lt;b&gt;NebulaGraph&lt;/b&gt; и его &lt;b&gt;nGQL&lt;/b&gt;.&lt;/li&gt;

&lt;ul&gt;
  &lt;li&gt;*Почему:* В AdTech сценариях (как у Meituan/Tencent) критичны latency на “хопах” (hops). nGQL архитектурно заставляет писать запросы так, чтобы они эффективно параллелились. Он менее удобен, чем Cypher, но более предсказуем в нагрузке.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;b&gt;Если приоритет — Real-time аналитика, ML-фичи и скорость разработки:&lt;/b&gt;  &lt;br /&gt;
Вам нужен &lt;b&gt;Memgraph&lt;/b&gt; на &lt;b&gt;Cypher&lt;/b&gt;.&lt;/li&gt;

&lt;ul&gt;
  &lt;li&gt;*Почему:* Вы получаете совместимость с самой популярной экосистемой (Neo4j), стандартный язык Cypher (легко найти специалистов) и скорость C++ in-memory движка.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="3"&gt;
&lt;li&gt;&lt;b&gt;Если приоритет — дешевое горизонтальное масштабирование “для бедных” (в хорошем смысле):&lt;/b&gt;  &lt;br /&gt;
Вам нужен &lt;b&gt;Dgraph&lt;/b&gt; (DQL) или &lt;b&gt;NebulaGraph&lt;/b&gt;.&lt;/li&gt;

&lt;ul&gt;
  &lt;li&gt;У &lt;b&gt;Dgraph&lt;/b&gt; отличный шардинг из коробки и DQL закрывает 90% задач продуктовой разработки, но может буксовать на тяжелой аналитике.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;b&gt;От чего стоит отказаться:&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Neo4j Community:&lt;/b&gt; Язык Cypher прекрасен, но ограничения лицензии (отсутствие кластера) убьют проект на росте.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;JanusGraph/HugeGraph (Gremlin):&lt;/b&gt; В 2025 году начинать проект на Gremlin — это создавать себе технический долг, так как индустрия движется в сторону ISO GQL (Cypher Style).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Apache AGE:&lt;/b&gt; Пока слишком сыро для High-load, проблемы с горизонтальным масштабированием Postgres никуда не деваются.&lt;/li&gt;
&lt;/ul&gt;
</description>
</item>

<item>
<title>Обзор pg_clickhouse: Как объединить мощь ClickHouse и удобство PostgreSQL</title>
<guid isPermaLink="false">302</guid>
<link>https://gavrilov.info/all/obzor-pg-clickhouse-kak-obedinit-mosch-clickhouse-i-udobstvo-pos/</link>
<pubDate>Fri, 12 Dec 2025 23:27:54 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/obzor-pg-clickhouse-kak-obedinit-mosch-clickhouse-i-udobstvo-pos/</comments>
<description>
&lt;p&gt;Недавно компания ClickHouse представила новый инструмент — расширение &lt;b&gt;pg_clickhouse&lt;/b&gt;. Это событие стало ответом на одну из самых частых болей разработчиков: сложность миграции аналитических запросов из классических реляционных баз данных в колоночные аналитические СУБД.&lt;/p&gt;
&lt;p&gt;Оригинал статьи: &lt;a href="https://clickhouse.com/blog/introducing-pg_clickhouse"&gt;A Postgres extension for querying ClickHouse&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;или берем сразу тут: &lt;a href="https://github.com/ClickHouse/pg_clickhouse/releases"&gt;https://github.com/ClickHouse/pg_clickhouse/releases&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;В этой статье мы разберем, что представляет собой этот инструмент, в чем его фундаментальный смысл для архитектуры приложений и куда проект хочет двигаться дальше.&lt;/p&gt;
&lt;h3&gt;Проблема: Данные переехали, а запросы остались&lt;/h3&gt;
&lt;p&gt;Типичный сценарий роста стартапа выглядит так: приложение строится на PostgreSQL. В какой-то момент данных (логов, метрик, транзакций) становится так много, что аналитические отчеты начинают тормозить. Обычные реплики для чтения (read replicas) перестают спасать.&lt;/p&gt;
&lt;p&gt;Команда принимает решение внедрить ClickHouse. Перенос данных сейчас решается просто (например, с помощью ClickPipes), но возникает другая проблема:&lt;br /&gt;
&lt;b&gt;Как быть с тысячами строк SQL-кода в ORM, дашбордах и скриптах, которые написаны под синтаксис Postgres?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Переписывание всей логики приложения под диалект ClickHouse — это месяцы работы и риск новых багов. Именно эту проблему решает `pg_clickhouse`.&lt;/p&gt;
&lt;h3&gt;Что такое pg_clickhouse?&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;pg_clickhouse&lt;/b&gt; — это расширение для PostgreSQL (Foreign Data Wrapper — FDW), которое позволяет создавать в Postgres «внешние таблицы», фактически ссылающиеся на таблицы в ClickHouse.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Суть технологии:&lt;/b&gt; Вы пишете запросы на привычном SQL диалекте PostgreSQL, обращаясь к этим таблицам. Расширение на лету транслирует запрос в диалект ClickHouse, отправляет его на исполнение в аналитическую базу и возвращает результат обратно в Postgres.&lt;/p&gt;
&lt;p&gt;Для приложения это выглядит прозрачно: таблицы ClickHouse могут находиться просто в отдельной схеме (schema). Достаточно изменить путь поиска (`search_path`), и старые запросы начнут работать с данными, лежащими в ClickHouse.&lt;/p&gt;
&lt;h3&gt;В чем «соль»: Технология Pushdown&lt;/h3&gt;
&lt;p&gt;Главная ценность и сложность такого расширения заключается не просто в соединении двух баз, а в эффективности этого соединения. Этот механизм называется &lt;b&gt;Pushdown&lt;/b&gt; (спуск или делегирование вычислений).&lt;/p&gt;
&lt;p&gt;Если вы делаете запрос `SELECT sum(price) FROM orders`, есть два пути его выполнения:&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Плохой путь:&lt;/b&gt; Postgres выкачивает *все* миллионы строк из ClickHouse и сам считает сумму. Это уничтожает весь смысл аналитической базы.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Путь pg_clickhouse:&lt;/b&gt; Расширение понимает, что это агрегация, и отправляет в ClickHouse команду «посчитай сумму». Обратно по сети возвращается только одна цифра.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Умная трансляция функций&lt;/h4&gt;
&lt;p&gt;Авторы `pg_clickhouse` пошли дальше простой трансляции. Они научили расширение переводить специфические функции Postgres в аналоги ClickHouse, даже если синтаксис кардинально отличается.&lt;/p&gt;
&lt;p&gt;*Пример:*&lt;br /&gt;
В Postgres есть функция для расчета медианы: `percentile_cont(0.5) WITHIN GROUP (ORDER BY price)`.&lt;br /&gt;
В ClickHouse такой синтаксис не поддерживается.&lt;br /&gt;
`pg_clickhouse` автоматически переписывает это в нативную функцию ClickHouse: `quantile(0.5)(price)`.&lt;/p&gt;
&lt;p&gt;Также поддерживается трансляция конструкции `FILTER (WHERE ...)` в специфичные для ClickHouse комбинаторы `-If` (например, `sumIf`).&lt;/p&gt;
&lt;h4&gt;Ускорение подзапросов (Semi-Join)&lt;/h4&gt;
&lt;p&gt;В версии 0.1.0 была реализована поддержка &lt;b&gt;SEMI JOIN Pushdown&lt;/b&gt;. Это критически важно для запросов с конструкцией `WHERE ... IN (SELECT ...)` или `EXISTS`. Тесты на бенчмарке TPC-H показали, что благодаря этому время выполнения сложных запросов сократилось с нескольких секунд (или даже минут) до миллисекунд, так как фильтрация теперь происходит на стороне ClickHouse.&lt;/p&gt;
&lt;h3&gt;Планы развития (Roadmap)&lt;/h3&gt;
&lt;p&gt;Проект находится в стадии активной разработки (версия 0.1.0), и команда ClickHouse нацелена на полное покрытие аналитических сценариев.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ключевые пункты плана:&lt;/b&gt;&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Полное покрытие TPC-H и ClickBench:&lt;/b&gt; Оптимизация планировщика, чтобы все стандартные аналитические бенчмарки выполнялись с максимальным pushdown-ом.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Расширенная поддержка функций:&lt;/b&gt; Трансляция *всех* агрегатных и обычных функций PostgreSQL в их эквиваленты в ClickHouse.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DML операции:&lt;/b&gt; Поддержка легковесных удалений (`DELETE`) и обновлений (`UPDATE`), а также пакетной вставки данных через `COPY`.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Управление настройками:&lt;/b&gt; Возможность передавать настройки ClickHouse (settings) через команды создания пользователей или серверов в Postgres.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Passthrough-режим:&lt;/b&gt; Возможность отправить произвольный SQL-запрос (на диалекте ClickHouse) и получить результат в виде таблицы, обходя парсер Postgres.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Заключение&lt;/h3&gt;
&lt;p&gt;`pg_clickhouse` — это попытка построить «лучшее из двух миров»: взять скорость колоночной СУБД и объединить её с богатой экосистемой и инструментарием PostgreSQL. Это позволяет разработчикам плавно мигрировать нагрузку, не переписывая приложение с нуля, и оставляет Postgres в качестве единой точки входа для данных.&lt;/p&gt;
</description>
</item>

<item>
<title>Битва Новых Архитектур: Сравниваем Arc, GigAPI и DuckLake</title>
<guid isPermaLink="false">286</guid>
<link>https://gavrilov.info/all/bitva-novyh-arhitektur-sravnivaem-arc-gigapi-i-ducklake/</link>
<pubDate>Sun, 12 Oct 2025 00:02:44 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/bitva-novyh-arhitektur-sravnivaem-arc-gigapi-i-ducklake/</comments>
<description>
&lt;p&gt;В мире данных происходит тихая революция. На смену тяжеловесным и дорогим OLAP-системам приходят легковесные, но мощные решения, построенные на идеологии Lakehouse. Они обещают гибкость озер данных и надежность хранилищ без лишней сложности и затрат.&lt;/p&gt;
&lt;p&gt;Можно еще почитать тут: &lt;a href="https://habr.com/ru/articles/955536/"&gt;https://habr.com/ru/articles/955536/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;В этой статье мы сравним два таких проекта для работы с временными рядами — &lt;b&gt;Arc&lt;/b&gt; и &lt;b&gt;GigAPI&lt;/b&gt;. А также разберемся, какое место в этой экосистеме занимает &lt;b&gt;DuckLake&lt;/b&gt; — технология, которую пока еще могут путать с Arc.&lt;/p&gt;
&lt;h4&gt;🆚 Arc vs. GigAPI: Сравнительная таблица&lt;/h4&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/image-220.png" width="1024" height="1024" alt="" /&gt;
&lt;/div&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/image-221.png" width="769" height="232" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Это прямые конкуренты, решающие задачу хранения и анализа временных рядов, но с разной философией.&lt;/p&gt;
&lt;table cellpadding="0" cellspacing="0" border="0" class="e2-text-table"&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Параметр&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Arc&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;GigAPI&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Основной подход&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Автономная Time-Series база данных «в одном файле» на базе DuckDB.&lt;/td&gt;
&lt;td style="text-align: center"&gt;Унифицированный слой для запросов и управления жизненным циклом данных (Lakehouse).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Стадия развития&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Альфа, &lt;b&gt;не для продакшена&lt;/b&gt;.&lt;/td&gt;
&lt;td style="text-align: center"&gt;Открытая бета, активные релизы.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Архитектура&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Монолитный бинарный файл, простой запуск.&lt;/td&gt;
&lt;td style="text-align: center"&gt;Набор микросервисов (`aio`, `readonly`, `writeonly`, `compaction`).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: right"&gt;&lt;b&gt;Производительность (ingest)&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Заявлено до &lt;b&gt;~1.89 млн записей/сек&lt;/b&gt; (нативным протоколом).&lt;/td&gt;
&lt;td style="text-align: center"&gt;Субсекундные аналитические запросы. Производительность ingest зависит от бэкенда.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Протоколы ввода данных&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;MessagePack (рекомендуемый), InfluxDB Line Protocol &lt;a href="https://github.com/Basekick-Labs/arc"&gt;arc&lt;/a&gt;.&lt;/td&gt;
&lt;td style="text-align: center"&gt;InfluxDB Line Protocol, Native JSON. Планируется FlightSQL &lt;a href="https://github.com/gigapi/gigapi"&gt;gigapi&lt;/a&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Управление данными&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;ACID-транзакции, Time Travel, Schema Evolution (унаследовано от Lakehouse-архитектуры).&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Автоматическая компакция&lt;/b&gt;, &lt;b&gt;перемещение данных (tiering)&lt;/b&gt; между FS и S3, &lt;b&gt;удаление по TTL&lt;/b&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Лицензия&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;AGPL-3.0&lt;/b&gt; (важное ограничение для коммерческого использования).&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;MIT&lt;/b&gt; (максимально разрешительная).&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;h4&gt;Ключевые отличия в подходах: Arc и GigAPI&lt;/h4&gt;
&lt;h5&gt;Arc: Максимальная простота и скорость для старта&lt;/h5&gt;
&lt;p&gt;&lt;b&gt;Arc&lt;/b&gt; &lt;a href="https://github.com/Basekick-Labs/arc"&gt;arc&lt;/a&gt; — это полноценная база данных временных рядов, которую можно скачать и запустить одной командой.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Идеология:&lt;/b&gt; “Батарейки в комплекте”. Arc предоставляет готовое решение с ACID-транзакциями, time travel и эволюцией схемы “из коробки”. Он спроектирован для максимальной простоты развертывания и сверхбыстрого приема данных.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Сценарий использования:&lt;/b&gt; Идеален для R&amp;D, прототипирования и внутренних проектов, где нужна высокая производительность без сложной настройки.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ключевой компромисс:&lt;/b&gt; Лицензия AGPL-3.0 требует, чтобы любое сетевое приложение, использующее Arc, также открывало свой исходный код. Это делает его неприменимым для многих коммерческих продуктов.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;GigAPI: Операционная мощь для продакшена&lt;/h5&gt;
&lt;p&gt;&lt;b&gt;GigAPI&lt;/b&gt; &lt;a href="https://github.com/gigapi/gigapi"&gt;gigapi&lt;/a&gt; — это не база данных, а скорее &lt;b&gt;интеллектуальный операционный слой&lt;/b&gt; или шлюз, который работает поверх ваших данных.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Идеология:&lt;/b&gt; “Оркестратор и оптимизатор”. GigAPI фокусируется на промышленной эксплуатации и автоматизации рутинных задач. Его микросервисы (`merge`, `move`, `drop`) следят за здоровьем хранилища: уплотняют мелкие файлы, перемещают старые данные в дешевое S3-хранилище и удаляют их по истечении срока жизни (TTL).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Сценарий использования:&lt;/b&gt; Построение зрелого, экономически эффективного и надежного пайплайна для временных рядов в production-среде. Разрешительная лицензия MIT делает его отличным выбором для бизнеса.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ключевое преимущество:&lt;/b&gt; Архитектурная гибкость и фокус на снижении эксплуатационных расходов (OpEx).&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;А где же DuckLake?&lt;/h4&gt;
&lt;p&gt;&lt;b&gt;DuckLake&lt;/b&gt; — это не база данных, а &lt;b&gt;открытый табличный формат&lt;/b&gt; и &lt;b&gt;расширение для DuckDB&lt;/b&gt; &lt;a href="https://github.com/duckdb/ducklake"&gt;ducklake&lt;/a&gt;. Его цель — упростить создание Lakehouse, используя SQL в качестве слоя метаданных &lt;a href="https://duckdb.org/2025/05/27/ducklake.html"&gt;ducklake blog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Представьте, что у вас есть набор Parquet-файлов в S3. Чтобы работать с ними как с единой таблицей и иметь транзакции, традиционно нужен сложный компонент вроде Hive Metastore или Nessie. DuckLake предлагает более простой путь:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Используйте обычную SQL-базу (например, DuckDB, SQLite или даже Postgres) для хранения всей метаинформации о файлах, версиях и схеме.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Таким образом, DuckLake — это &lt;b&gt;фундаментальный строительный блок&lt;/b&gt;, а не готовое приложение. Он конкурирует с Apache Iceberg и Delta Lake, предлагая более простую альтернативу. Недавние обновления даже добавили &lt;b&gt;совместимость с Iceberg&lt;/b&gt;, что делает его еще более мощным инструментом &lt;a href="https://ducklake.select/2025/09/17/ducklake-03/"&gt;ducklake.select&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Сравнение с рынком: Альтернативы и выбор&lt;/h4&gt;
&lt;table cellpadding="0" cellspacing="0" border="0" class="e2-text-table"&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Система&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Сильные стороны&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Слабые стороны / Риски&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;InfluxDB 3.0&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Зрелая экосистема для временных рядов, Lakehouse архитектура “под капотом”.&lt;/td&gt;
&lt;td style="text-align: center"&gt;Стоимость для enterprise, привязка к своей экосистеме.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;QuestDB&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Высокая скорость вставок и SQL-запросов, простой опыт TSDB.&lt;/td&gt;
&lt;td style="text-align: center"&gt;Менее универсален для “озер” на S3, чем конкуренты.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;TimescaleDB&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Полная совместимость с экосистемой PostgreSQL.&lt;/td&gt;
&lt;td style="text-align: center"&gt;Привязанность к PostgreSQL и его модели масштабирования.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;ClickHouse&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Универсальный OLAP-движок, мощные возможности для временных рядов, горизонтальное масштабирование.&lt;/td&gt;
&lt;td style="text-align: center"&gt;Высокие эксплуатационные расходы, сложность настройки кластера.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;h4&gt;Когда что выбирать?&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Выберите Arc&lt;/b&gt;, если вам нужен &lt;b&gt;максимально быстрый старт&lt;/b&gt; для прототипа или внутреннего проекта, вы не боитесь альфа-версии и вас полностью устраивает &lt;b&gt;лицензия AGPL-3.0&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Выберите GigAPI&lt;/b&gt;, если вы строите &lt;b&gt;продакшн-систему&lt;/b&gt;, вам важна &lt;b&gt;автоматизация рутинных задач&lt;/b&gt; (compaction, tiering, TTL) и нужна &lt;b&gt;разрешительная лицензия MIT&lt;/b&gt; для коммерческого использования.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Используйте DuckLake&lt;/b&gt;, если вы уже работаете с DuckDB и хотите построить &lt;b&gt;свой собственный, простой Lakehouse&lt;/b&gt; на базе Parquet-файлов, избегая сложности стека Hadoop/Spark.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Обратитесь к ClickHouse/Druid&lt;/b&gt;, когда нужны &lt;b&gt;жесткие SLA, горизонтальное масштабирование&lt;/b&gt; и высокий параллелизм для тысяч одновременных пользователей.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Рассмотрите QuestDB/Timescale&lt;/b&gt;, если приоритетом является &lt;b&gt;предельно простой опыт работы с TSDB&lt;/b&gt; или глубокая интеграция с экосистемой Postgres.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Заключение&lt;/h4&gt;
&lt;p&gt;&lt;b&gt;Arc&lt;/b&gt;, &lt;b&gt;GigAPI&lt;/b&gt; и &lt;b&gt;DuckLake&lt;/b&gt; — яркие представители тренда на прагматичные и экономичные решения для данных.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Arc&lt;/b&gt; — спринтер для быстрого старта.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;GigAPI&lt;/b&gt; — марафонец для надежной работы в продакшене.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DuckLake&lt;/b&gt; — набор инструментов для архитектора, позволяющий построить легковесный и современный дом для данных.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Их появление говорит о том, что рынку нужны не только монструозные системы, но и решения с оптимальным соотношением “простота/стоимость/функциональность”.&lt;/p&gt;
&lt;p&gt;Вот так выглядит:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2025-10-11-v-23.58.08.png" width="2094" height="1162" alt="" /&gt;
&lt;/div&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;services:
  gigapi:
    image: ghcr.io/gigapi/gigapi:latest
    container_name: gigapi
    hostname: gigapi
    restart: unless-stopped
    volumes:
      - ./data:/data
    ports:
      - &amp;quot;7971:7971&amp;quot;
      - &amp;quot;8082:8082&amp;quot;
    environment:
      - PORT=7971
      - GIGAPI_ENABLED=true
      - GIGAPI_MERGE_TIMEOUT_S=10
      - GIGAPI_ROOT=/data
      - GIGAPI_LAYERS_0_NAME=default
      - GIGAPI_LAYERS_0_TYPE=fs
      - GIGAPI_LAYERS_0_URL=file:///data
      - GIGAPI_LAYERS_0_GLOBAL=false
      - GIGAPI_LAYERS_0_TTL=12h
      - GIGAPI_LAYERS_1_NAME=s3
      - GIGAPI_LAYERS_1_TYPE=s3
      - GIGAPI_LAYERS_1_URL=s3://gateway.XXXXX/test/gigapi
      - GIGAPI_LAYERS_1_AUTH_KEY=XXXXX
      - GIGAPI_LAYERS_1_AUTH_SECRET=XXXXX
      - GIGAPI_LAYERS_1_GLOBAL=true
      - GIGAPI_LAYERS_1_TTL=0&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;А данные пишем так:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;cat &amp;lt;&amp;lt;EOF | curl -X POST &amp;quot;http://localhost:7971/write?db=mydb&amp;quot; --data-binary @/dev/stdin
weather,location=us-midwest,season=summer temperature=82
weather,location=us-east,season=summer temperature=123
weather,location=us-west,season=summer temperature=111
EOF&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Первый раз нужно отправить сообщение, что бы создалась база.&lt;/p&gt;
&lt;p&gt;файлики пишет, но че то пока не на s3, видимо надо дождаться как они переедут с кеша на s3&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2025-10-12-v-00.01.54.png" width="924" height="444" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Выше пример не сработал, точнее он работал, но не копировал данные на s3&lt;/p&gt;
&lt;p&gt;вот это рабочий вариант&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;# docker-compose.yml
version: '3.8'

services:
  gigapi:
    build: . 
    container_name: gigapi
    restart: unless-stopped
    volumes:
      - ./gigapi_data:/data
    ports:
      - &amp;quot;7971:7971&amp;quot;
      - &amp;quot;8082:8082&amp;quot;
    environment:
      # --- Общие настройки GigAPI ---
      - GIGAPI_ROOT=/data 
      - HTTP_PORT=7971
      - LOGLEVEL=info
      - GIGAPI_UI=true

      # --- Конфигурация Слоя 0: Локальный кэш на диске ---
      - GIGAPI_LAYERS_0_NAME=local_cache
      - GIGAPI_LAYERS_0_TYPE=fs
      - GIGAPI_LAYERS_0_URL=file:///data/cache
      - GIGAPI_LAYERS_0_GLOBAL=false
      - GIGAPI_LAYERS_0_TTL=10m

      # --- Конфигурация Слоя 1: Хранилище Storj S3 ---
      - GIGAPI_LAYERS_1_NAME=storj_s3
      - GIGAPI_LAYERS_1_TYPE=s3
      - GIGAPI_LAYERS_1_URL=s3://gateway.storjshare.io/test/gigapi/data?url-style=path
      - GIGAPI_LAYERS_1_AUTH_KEY=XXXXXX
      - GIGAPI_LAYERS_1_AUTH_SECRET=XXXXX
      - GIGAPI_LAYERS_1_GLOBAL=true
      - GIGAPI_LAYERS_1_TTL=0&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;И пришлось серты обновить&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;# Dockerfile

# Берем за основу официальный образ gigapi
FROM ghcr.io/gigapi/gigapi:latest

# Переключаемся на пользователя root для установки пакетов
USER root

# Обновляем список пакетов и устанавливаем корневые сертификаты.
# Эта команда сначала пытается использовать 'apt-get' (для Debian/Ubuntu).
# Если эта команда завершается с ошибкой (оператор ||), то
# выполняется вторая команда с 'apk' (для Alpine).
# Это делает Dockerfile более универсальным.
RUN if command -v apt-get &amp;amp;&amp;gt; /dev/null; then \
        apt-get update &amp;amp;&amp;amp; apt-get install -y --no-install-recommends ca-certificates &amp;amp;&amp;amp; apt-get clean &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*; \
    elif command -v apk &amp;amp;&amp;gt; /dev/null; then \
        apk add --no-cache ca-certificates; \
    else \
        echo &amp;quot;Error: Neither apt-get nor apk found. Cannot install ca-certificates.&amp;quot; &amp;gt;&amp;amp;2; \
        exit 1; \
    fi

# Возвращаемся к стандартному пользователю (если он есть)
# USER gigapi&lt;/code&gt;&lt;/pre&gt;&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2025-10-13-v-22.34.22.png" width="1492" height="176" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Там кстати еще чатгпт апи можно вставить&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2025-10-13-v-22.37.35.png" width="1588" height="1216" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;И дашборды есть еще&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2025-10-13-v-22.39.54.png" width="1710" height="642" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Еще про s3 подобные архитектуры:&lt;br /&gt;
&lt;a href="https://gavrilov.info/all/sozdaem-streaming-lakehouse-za-chas-rukovodstvo-po-risingwave-la"&gt;https://gavrilov.info/all/sozdaem-streaming-lakehouse-za-chas-rukovodstvo-po-risingwave-la&lt;/a&gt;&lt;/p&gt;
</description>
</item>

<item>
<title>Выбираем базы данных</title>
<guid isPermaLink="false">94</guid>
<link>https://gavrilov.info/all/vybiraem-bazy-dannyh/</link>
<pubDate>Sun, 10 Dec 2023 22:19:55 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/vybiraem-bazy-dannyh/</comments>
<description>
&lt;p&gt;Статья с хабра про выбор баз данных&lt;br /&gt;
&lt;a href="https://habr.com/ru/articles/775574/"&gt;https://habr.com/ru/articles/775574/&lt;/a&gt;&lt;/p&gt;
</description>
</item>


</channel>
</rss>