<?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>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>