> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Эквивалентные понятия в ClickStack и Elastic

> Эквивалентные понятия — ClickStack и Elastic

export const Image = ({img, alt, size}) => {
  return <Frame>
      <img src={img} alt={alt} />
    </Frame>;
};

<div id="elastic-vs-clickstack">
  ## Elastic Stack vs ClickStack
</div>

И Elastic Stack, и ClickStack охватывают ключевые роли платформы обсервабилити, но реализуют их в соответствии с разными архитектурными подходами. Эти роли включают:

* **Интерфейс и оповещения**: инструменты для выполнения запросов к данным, создания панелей мониторинга и управления оповещениями.
* **Хранилище и движок запросов**: backend-системы, отвечающие за хранение данных обсервабилити и выполнение аналитических запросов.
* **Сбор данных и ETL**: агенты и конвейеры, которые собирают данные телеметрии и обрабатывают их перед ингестией.

В таблице ниже показано, как каждый стек соотносит свои компоненты с этими ролями:

| **Роль**                        | **Elastic Stack**                                                        | **ClickStack**                                                                | **Комментарии**                                                                                                                                                                                                                           |
| ------------------------------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Интерфейс и оповещения**      | **Kibana** — панели мониторинга, поиск и оповещения                      | **ClickStack UI (HyperDX)** — интерфейс реального времени, поиск и оповещения | Оба служат основным интерфейсом для пользователей, включая визуализации и управление оповещениями. Интерфейс ClickStack специально разработан для задач обсервабилити и тесно связан с семантикой OpenTelemetry.                          |
| **Хранилище и движок запросов** | **Elasticsearch** — хранилище JSON-документов с инвертированным индексом | **ClickHouse** — столбцовая база данных с векторизованным движком             | Elasticsearch использует инвертированный индекс, оптимизированный для поиска; ClickHouse использует столбцовое хранение и SQL для высокоскоростной аналитики по структурированным и полуструктурированным данным.                         |
| **Сбор данных**                 | **Elastic Agent**, **Beats** (например, Filebeat, Metricbeat)            | **OpenTelemetry Collector** (edge + шлюз)                                     | Elastic поддерживает пользовательские компоненты-отправители и единый агент под управлением Fleet. ClickStack опирается на OpenTelemetry, что позволяет организовать независимый от вендора сбор и обработку данных.                      |
| **SDK для инструментирования**  | **Elastic APM agents** (проприетарные)                                   | **OpenTelemetry SDKs** (распространяемые вместе с ClickStack)                 | SDK Elastic привязаны к стеку Elastic. ClickStack строится на OpenTelemetry SDKs для журналов, метрик и трасс на основных языках.                                                                                                         |
| **ETL / Обработка данных**      | **Logstash**, ingest pipelines                                           | **OpenTelemetry Collector** + ClickHouse materialized views                   | Elastic использует ingest pipelines и Logstash для преобразования данных. ClickStack переносит вычисления на момент вставки с помощью materialized views и processors в OTel collector, которые эффективно и поэтапно преобразуют данные. |
| **Архитектурная философия**     | Вертикально интегрированный стек, проприетарные агенты и форматы         | Основанные на открытых стандартах, слабо связанные компоненты                 | Elastic строит тесно интегрированную экосистему. ClickStack делает акцент на модульности и стандартах (OpenTelemetry, SQL, Объектное хранилище), обеспечивая гибкость и экономическую эффективность.                                      |

ClickStack делает акцент на открытых стандартах и интероперабельности, будучи полностью построенным на OpenTelemetry — от сбора данных до интерфейса. В отличие от него, Elastic предлагает тесно связанный, но более вертикально интегрированный стек с проприетарными агентами и форматами.

Поскольку **Elasticsearch** и **ClickHouse** — это основные движки, отвечающие за хранение, обработку данных и выполнение запросов в соответствующих стеках, понимание их различий имеет решающее значение. Именно эти системы определяют производительность, масштабируемость и гибкость всей архитектуры обсервабилити. В следующем разделе рассматриваются ключевые различия между Elasticsearch и ClickHouse, включая то, как они моделируют данные, обрабатывают ингестию, выполняют запросы и управляют хранением.

<div id="elasticsearch-vs-clickhouse">
  ## Elasticsearch vs ClickHouse
</div>

ClickHouse и Elasticsearch организуют данные и выполняют запросы, опираясь на разные базовые модели, но многие ключевые концепции выполняют схожие функции. В этом разделе приведены основные соответствия для тех, кто знаком с Elastic, и показано, как эти понятия соотносятся с их аналогами в ClickHouse. Хотя терминология различается, большинство сценариев обсервабилити можно воспроизвести в ClickStack — зачастую даже эффективнее.

<div id="core-structural-concepts">
  ### Основные структурные понятия
</div>

| **Elasticsearch** | **ClickHouse / SQL**      | **Описание**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ----------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Поле**          | **Столбец**               | Базовая единица данных, содержащая одно или несколько значений определенного типа. Поля Elasticsearch могут хранить примитивные значения, а также массивы и объекты. Поле может иметь только один тип. ClickHouse также поддерживает массивы и объекты (`Tuples`, `Maps`, `Nested`), а также динамические типы, такие как [`Variant`](/ru/reference/data-types/variant) и [`Dynamic`](/ru/reference/data-types/dynamic), которые позволяют одному столбцу содержать значения нескольких типов. |
| **Документ**      | **Строка**                | Набор полей (столбцов). Документы Elasticsearch по умолчанию более гибкие: новые поля динамически добавляются на основе данных (тип определяется по данным). Строки ClickHouse по умолчанию привязаны к схеме, и пользователи должны вставлять все столбцы строки или их подмножество. Тип [`JSON`](/ru/guides/clickhouse/data-formats/json/intro) в ClickHouse поддерживает аналогичное создание полуструктурированных динамических столбцов на основе вставленных данных.                    |
| **Индекс**        | **Таблица**               | Единица выполнения запросов и хранения данных. В обеих системах запросы выполняются по индексам или таблицам, в которых хранятся строки/документы.                                                                                                                                                                                                                                                                                                                                             |
| *Неявно*          | Схема (SQL)               | SQL-схемы группируют таблицы в пространства имен и часто используются для управления доступом. В Elasticsearch и ClickHouse схем нет, но обе системы поддерживают безопасность на уровне строк и таблиц через роли и RBAC.                                                                                                                                                                                                                                                                     |
| **Кластер**       | **Кластер / База данных** | Кластеры Elasticsearch — это экземпляры среды выполнения, управляющие одним или несколькими индексами. В ClickHouse базы данных организуют таблицы в логическом пространстве имен, обеспечивая ту же логическую группировку, что и кластер в Elasticsearch. Кластер ClickHouse — это распределенный набор узлов, аналогичный Elasticsearch, но он отделен от самих данных и не зависит от них.                                                                                                 |

<div id="data-modeling-and-flexibility">
  ### Моделирование данных и гибкость
</div>

Elasticsearch известен гибкостью схемы благодаря [dynamic mappings](https://www.elastic.co/docs/manage-data/data-store/mapping/dynamic-mapping). Поля создаются по мере приёма документов, а типы определяются автоматически — если только схема не задана явно. ClickHouse по умолчанию более строг: таблицы определяются с явными схемами, — но обеспечивает гибкость за счёт типов [`Dynamic`](/ru/reference/data-types/dynamic), [`Variant`](/ru/reference/data-types/variant) и [`JSON`](/ru/guides/clickhouse/data-formats/json/intro). Они позволяют выполнять ингестию полуструктурированных данных с динамическим созданием столбцов и автоматическим определением типов, как в Elasticsearch. Аналогично, тип [`Map`](/ru/reference/data-types/map) позволяет хранить произвольные пары ключ-значение, хотя и ключ, и значение при этом должны иметь один и тот же тип.

Подход ClickHouse к гибкости типов более прозрачен и управляем. В отличие от Elasticsearch, где конфликты типов могут вызывать ошибки ингестии, ClickHouse позволяет хранить данные смешанных типов в столбцах [`Variant`](/ru/reference/data-types/variant) и поддерживает эволюцию схемы за счёт использования типа [`JSON`](/ru/guides/clickhouse/data-formats/json/intro).

Если [`JSON`](/ru/guides/clickhouse/data-formats/json/intro) не используется, схема задаётся статически. Если для строки значения не указаны, соответствующие столбцы должны иметь тип [`Nullable`](/ru/reference/data-types/nullable) (в ClickStack не используется), либо для них будет использовано значение по умолчанию для данного типа, например пустое значение для `String`.

<div id="ingestion-and-transformation">
  ### Ингестия и преобразование
</div>

Elasticsearch использует конвейеры ингестии с процессорами (например, `enrich`, `rename`, `grok`) для преобразования документов перед индексацией. В ClickHouse аналогичная функциональность достигается с помощью [**incremental materialized views**](/ru/concepts/features/materialized-views/incremental-materialized-view), которые могут [фильтровать и преобразовывать](/ru/concepts/features/materialized-views/incremental-materialized-view#filtering-and-transformation) или [обогащать](/ru/concepts/features/materialized-views/incremental-materialized-view#lookup-table) входящие данные и вставлять результаты в целевые таблицы. Вы также можете вставлять данные в движок таблицы `Null`, если нужно хранить только вывод materialized view. Это означает, что сохраняются только результаты materialized view, а исходные данные отбрасываются, что позволяет экономить место в хранилище.

Для обогащения Elasticsearch поддерживает специальные [enrich processors](https://www.elastic.co/docs/reference/enrich-processor/enrich-processor), которые добавляют контекст к документам. В ClickHouse [**словари**](/ru/concepts/features/dictionaries) можно использовать как [во время выполнения запроса](/ru/concepts/features/dictionaries#query-time-enrichment), так и [на этапе ингестии](/ru/concepts/features/dictionaries#index-time-enrichment), чтобы обогащать строки — например, для [сопоставления IP-адресов с местоположениями](/ru/guides/use-cases/observability/build-your-own/schema-design#using-ip-dictionaries) или [lookup-операций по user-agent](/ru/guides/use-cases/observability/build-your-own/schema-design#using-regex-dictionaries-user-agent-parsing) при вставке.

<div id="query-languages">
  ### Языки запросов
</div>

Elasticsearch поддерживает [ряд языков запросов](https://www.elastic.co/docs/explore-analyze/query-filter/languages), включая [DSL](https://www.elastic.co/docs/explore-analyze/query-filter/languages/querydsl), [ES|QL](https://www.elastic.co/docs/explore-analyze/query-filter/languages/esql), [EQL](https://www.elastic.co/docs/explore-analyze/query-filter/languages/eql) и запросы [KQL](https://www.elastic.co/docs/explore-analyze/query-filter/languages/kql) (в стиле Lucene), но поддержка JOIN в нем ограничена — через [`ES|QL`](https://www.elastic.co/guide/en/elasticsearch/reference/8.x/esql-commands.html#esql-lookup-join) доступны только **левые внешние JOIN**. ClickHouse поддерживает **полный синтаксис SQL**, включая [все типы JOIN](/ru/reference/statements/select/join#supported-types-of-join), [оконные функции](/ru/reference/functions/window-functions), подзапросы (в том числе коррелированные) и CTE. Это важное преимущество, если вам нужно коррелировать сигналы обсервабилити с бизнес-данными или данными инфраструктуры.

В ClickStack [в интерфейсе доступен совместимый с Lucene поиск](/ru/clickstack/features/search), что упрощает переход, наряду с полной поддержкой SQL через ClickHouse. Этот синтаксис сопоставим с синтаксисом [query string в Elastic](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-query-string-query#query-string-syntax). Точное сравнение этого синтаксиса см. в статье ["Поиск в ClickStack и Elastic"](/ru/clickstack/migration/elastic/search).

<div id="file-formats-and-interfaces">
  ### Форматы файлов и интерфейсы
</div>

Elasticsearch поддерживает приём данных в формате JSON (а также [ограниченную поддержку CSV](https://www.elastic.co/docs/reference/enrich-processor/csv-processor)). ClickHouse поддерживает более **70 форматов файлов**, включая Parquet, Protobuf, Arrow, CSV и другие — как для ингестии, так и для экспорта. Это упрощает интеграцию с внешними конвейерами и инструментами.

Обе системы предоставляют REST API, но ClickHouse также поддерживает **собственный протокол** для взаимодействия с низкой задержкой и высокой пропускной способностью. Интерфейс на собственном протоколе эффективнее HTTP поддерживает прогресс выполнения запроса, сжатие и стриминг и по умолчанию используется в большинстве production-сценариев ингестии.

<div id="indexing-and-storage">
  ### Индексирование и хранение
</div>

<Image img="https://mintcdn.com/private-7c7dfe99-fix-nav-issues/FZqG0tBuMc0GoOY1/images/use-cases/observability/elasticsearch.png?fit=max&auto=format&n=FZqG0tBuMc0GoOY1&q=85&s=63b94f6982d603bb7d77ea99944fd585" alt="Elasticsearch" size="lg" width="1606" height="1090" data-path="images/use-cases/observability/elasticsearch.png" />

Концепция сегментирования лежит в основе модели масштабируемости Elasticsearch. Каждый ① [**индекс**](https://www.elastic.co/blog/what-is-an-elasticsearch-index) разбивается на **сегменты**, каждый из которых представляет собой физический индекс Lucene, хранящийся на диске в виде сегментов. Сегмент может иметь одну или несколько физических копий, называемых сегментами-репликами, для отказоустойчивости. Для масштабирования сегменты и реплики могут быть распределены по нескольким узлам. Один сегмент ② состоит из одного или нескольких неизменяемых сегментов Lucene. Сегмент Lucene — это базовая структура индексирования в библиотеке Java Lucene, которая предоставляет возможности индексирования и поиска, лежащие в основе Elasticsearch.

<Info>
  **Обработка вставки в Elasticsearch**

  Ⓐ Новые документы Ⓑ сначала попадают в буфер индексирования в памяти, который по умолчанию сбрасывается раз в секунду. Для определения целевого сегмента для сброшенных документов используется формула маршрутизации, после чего для этого сегмента на диске записывается новый сегмент Lucene. Чтобы повысить эффективность запросов и обеспечить физическое удаление удалённых или обновлённых документов, сегменты Lucene постоянно сливаются в фоновом режиме в более крупные сегменты, пока не достигнут максимального размера 5 ГБ. При этом при необходимости можно принудительно выполнить слияние в ещё более крупные сегменты.
</Info>

Elasticsearch рекомендует выбирать размер сегментов около [50 ГБ или 200 миллионов документов](https://www.elastic.co/docs/deploy-manage/production-guidance/optimize-performance/size-shards) из-за [накладных расходов на JVM heap и метаданные](https://www.elastic.co/docs/deploy-manage/production-guidance/optimize-performance/size-shards#each-shard-has-overhead). Также существует жёсткий предел в [2 миллиарда документов на сегмент](https://www.elastic.co/docs/deploy-manage/production-guidance/optimize-performance/size-shards#troubleshooting-max-docs-limit). Elasticsearch распараллеливает запросы по сегментам, но каждый сегмент обрабатывается **одним потоком**, из-за чего чрезмерное сегментирование становится и дорогим, и контрпродуктивным. Это по своей природе жёстко связывает сегментирование с масштабированием: для увеличения производительности требуется больше сегментов (и узлов).

Elasticsearch индексирует все поля в [**инвертированных индексах**](https://www.elastic.co/docs/manage-data/data-store/index-basics) для быстрого поиска, а также при необходимости использует [**doc values**](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/doc-values) для агрегаций, сортировки и доступа к полям из скриптов. Для числовых и географических полей используются [деревья Block K-D](https://users.cs.duke.edu/~pankaj/publications/papers/bkd-sstd.pdf) для поиска по геопространственным данным, а также по числовым диапазонам и диапазонам дат.

Важно, что Elasticsearch хранит полный исходный документ в [`_source`](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/mapping-source-field) (в сжатом виде с помощью `LZ4`, `Deflate` или `ZSTD`), тогда как ClickHouse не хранит отдельное представление документа. Данные восстанавливаются из столбцов во время выполнения запроса, что экономит место в хранилище. Аналогичная возможность доступна в Elasticsearch через [Synthetic `_source`](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/mapping-source-field#synthetic-source), но с некоторыми [ограничениями](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/mapping-source-field#synthetic-source-restrictions). Отключение `_source` также имеет [последствия](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/mapping-source-field#include-exclude), которые для ClickHouse неактуальны.

В Elasticsearch [mapping индекса](https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html) (эквивалент схем таблиц в ClickHouse) определяют типы полей и структуры данных, используемые для такого хранения и выполнения запросов.

ClickHouse, напротив, — **колоночно-ориентированная** система: каждый столбец хранится независимо, но всегда отсортирован по первичному ключу/ключу сортировки таблицы. Такая упорядоченность позволяет использовать [разреженные первичные индексы](/ru/concepts/core-concepts/primary-indexes), благодаря которым ClickHouse может эффективно пропускать данные во время выполнения запроса. Когда запросы фильтруются по полям первичного ключа, ClickHouse читает только релевантные части каждого столбца, существенно сокращая дисковый ввод-вывод и повышая производительность — даже без полного индекса для каждого столбца.

<Image img="https://mintcdn.com/private-7c7dfe99-fix-nav-issues/FZqG0tBuMc0GoOY1/images/use-cases/observability/clickhouse.png?fit=max&auto=format&n=FZqG0tBuMc0GoOY1&q=85&s=0037a1faa15eb2754ef4689567ec6fae" alt="ClickHouse" size="lg" width="1608" height="1100" data-path="images/use-cases/observability/clickhouse.png" />

ClickHouse также поддерживает [**индексы пропуска данных**](/ru/concepts/features/performance/skip-indexes/skipping-indexes), которые ускоряют фильтрацию за счёт предварительного вычисления индексных данных для выбранных столбцов. Их нужно явно определять, но они могут значительно повысить производительность. Кроме того, ClickHouse позволяет задавать [кодеки сжатия](/ru/guides/use-cases/observability/build-your-own/schema-design#using-codecs) и алгоритмы сжатия для каждого столбца — Elasticsearch такого не поддерживает (его [сжатие](https://www.elastic.co/docs/reference/elasticsearch/index-settings/index-modules) применяется только к хранению JSON в `_source`).

ClickHouse также поддерживает сегментирование, но его архитектура ориентирована прежде всего на **вертикальное масштабирование**. Один сегмент может хранить **триллионы строк** и при этом работать эффективно, пока это позволяют память, CPU и диск. В отличие от Elasticsearch, у сегмента **нет жесткого ограничения на число строк**. Сегменты в ClickHouse логические — по сути, это отдельные таблицы, — и не требуют партиционирования, если только набор данных не превышает емкость одного узла. Обычно это происходит из-за ограничений по объему диска, и сегментирование ① применяют только тогда, когда действительно необходимо горизонтальное масштабирование, — это снижает сложность и накладные расходы. В этом случае, как и в Elasticsearch, сегмент будет хранить подмножество данных. Данные внутри одного сегмента организованы как набор ② неизменяемых частей данных, содержащих ③ несколько структур данных.

Обработка внутри сегмента ClickHouse **полностью распараллелена**, и пользователям рекомендуется масштабироваться вертикально, чтобы избежать сетевых затрат, связанных с перемещением данных между узлами.

<Info>
  **Обработка вставок в ClickHouse**

  Вставки в ClickHouse **по умолчанию синхронные** — запись подтверждается только после коммита, — но можно настроить **асинхронные вставки**, чтобы получить буферизацию и батчинг, как в Elastic. Если используются [асинхронные вставки данных](https://clickhouse.com/blog/asynchronous-data-inserts-in-clickhouse), Ⓐ новые строки сначала попадают в Ⓑ буфер вставки в памяти, который по умолчанию сбрасывается раз в 200 миллисекунд. Если используется несколько сегментов, для маршрутизации новых строк в нужный сегмент используется [distributed таблица](/ru/reference/engines/table-engines/special/distributed). Затем для сегмента на диске записывается новая часть.
</Info>

<div id="distribution-and-replication">
  ### Распределение и репликация
</div>

Хотя и Elasticsearch, и ClickHouse используют кластеры, сегменты и реплики для обеспечения масштабируемости и отказоустойчивости, их модели существенно различаются по реализации и характеристикам производительности.

Elasticsearch использует для репликации модель **primary-secondary**. Когда данные записываются в основной сегмент, они синхронно копируются в одну или несколько реплик. Эти реплики сами по себе представляют собой полные сегменты, распределенные по узлам для обеспечения избыточности. Elasticsearch подтверждает запись только после того, как все требуемые реплики подтвердят операцию, — такая модель обеспечивает почти **последовательную согласованность**, хотя до полной синхронизации с реплик возможны **грязные чтения**. **Master node** координирует кластер, управляя распределением сегментов, его состоянием и выбором лидера.

Напротив, ClickHouse по умолчанию использует **eventual consistency**, координируемую с помощью **Keeper** — легковесной альтернативы ZooKeeper. Записи можно отправлять напрямую в любую реплику или через [**distributed таблицу**](/ru/reference/engines/table-engines/special/distributed), которая автоматически выбирает реплику. Репликация асинхронная — изменения распространяются на другие реплики уже после подтверждения записи. Для более строгих гарантий ClickHouse [поддерживает **последовательную согласованность**](/ru/get-started/migrate/postgres/appendix#sequential-consistency), при которой запись подтверждается только после фиксации на репликах, хотя этот режим используется редко из-за влияния на производительность. Distributed tables объединяют доступ к нескольким сегментам, перенаправляя запросы `SELECT` на все сегменты и объединяя результаты. Для операций `INSERT` они балансируют нагрузку, равномерно распределяя данные между сегментами. Репликация в ClickHouse очень гибкая: любая реплика (копия сегмента) может принимать записи, а все изменения асинхронно синхронизируются с остальными. Такая архитектура позволяет без перерывов обслуживать запросы во время сбоев или обслуживания, а повторная синхронизация выполняется автоматически, что устраняет необходимость в жестком соблюдении схемы primary-secondary на уровне данных.

<Info>
  **ClickHouse Cloud**

  В **ClickHouse Cloud** архитектура использует shared-nothing-модель вычислений, в которой один **сегмент опирается на объектное хранилище**. Это заменяет традиционную **Высокую доступность** на основе реплик, позволяя **нескольким узлам одновременно читать и записывать один и тот же сегмент**. Разделение хранилища и вычислений обеспечивает эластичное масштабирование без явного управления репликами.
</Info>

Вкратце:

* **Elastic**: Сегменты представляют собой физические структуры Lucene, привязанные к памяти JVM. Избыточное количество сегментов снижает производительность. Репликация синхронная и координируется master node.
* **ClickHouse**: Сегменты логические и вертикально масштабируемые, с очень эффективным локальным выполнением. Репликация асинхронная (но может быть последовательной), а координация — легковесная.

В конечном счете ClickHouse делает ставку на простоту и производительность в масштабе, сводя к минимуму необходимость тонкой настройки сегментов и при этом сохраняя строгие гарантии согласованности, когда это необходимо.

<div id="deduplication-and-routing">
  ### Дедупликация и маршрутизация
</div>

Elasticsearch удаляет дубликаты документов на основе их `_id`, направляя их в соответствующие сегменты. ClickHouse не хранит идентификатор строки по умолчанию, но поддерживает **дедупликацию при вставке**, позволяя пользователям безопасно повторять неудачные вставки. Для большего контроля `ReplacingMergeTree` и другие движки таблиц поддерживают дедупликацию по заданным столбцам.

Маршрутизация индекса в Elasticsearch гарантирует, что определённые документы всегда направляются в определённые сегменты. В ClickHouse можно определить **ключи сегментации** или использовать таблицы `Distributed`, чтобы добиться схожей локальности данных.

<div id="aggregations-execution-model">
  ### Агрегации и модель выполнения
</div>

Хотя обе системы поддерживают агрегацию данных, ClickHouse предлагает значительно [больше функций](/ru/reference/functions/aggregate-functions/reference-index), включая статистические, приближенные и специализированные аналитические функции.

В сценариях обсервабилити одно из самых распространенных применений агрегаций — подсчет того, как часто появляются определенные сообщения лога или события (с оповещением, если частота выходит за пределы нормы).

Эквивалентом SQL-запроса ClickHouse `SELECT count(*) FROM ... GROUP BY ...` в Elasticsearch является [terms aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html), то есть один из видов [bucket aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket.html) в Elasticsearch.

`GROUP BY` в ClickHouse с `count(*)` и terms aggregation в Elasticsearch в целом эквивалентны по функциональности, но заметно различаются по реализации, производительности и качеству результатов.

В Elasticsearch эта агрегация [оценивает результаты в запросах "top-N"](https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-terms-aggregation#terms-agg-doc-count-error) (например, при выводе 10 хостов с наибольшим числом событий), если запрашиваемые данные распределены по нескольким сегментам. Это ускоряет выполнение, но может снижать точность. Уменьшить эту ошибку можно, [проверяя `doc_count_error_upper_bound`](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html#terms-agg-doc-count-error) и увеличивая параметр `shard_size` — ценой роста использования памяти и снижения производительности запроса.

Elasticsearch также требует указывать настройку [`size`](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html#search-aggregations-bucket-terms-aggregation-size) для всех агрегаций по бакетам — вернуть все уникальные группы без явного лимита невозможно. Агрегации с большим числом уникальных значений могут упереться в [ограничение `max_buckets`](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-settings.html#search-settings-max-buckets) или потребовать постраничного обхода с помощью [composite aggregation](https://www.elastic.co/docs/reference/aggregations/bucket/composite-aggregation), что часто оказывается сложным и неэффективным.

ClickHouse, напротив, выполняет точные агрегации из коробки. Такие функции, как `count(*)`, возвращают точные результаты без дополнительных изменений конфигурации, благодаря чему поведение запросов становится проще и предсказуемее.

ClickHouse не накладывает ограничений на размер. Вы можете выполнять неограниченные запросы `GROUP BY` на больших датасетах. Если превышены пороги памяти, ClickHouse [может выгружать промежуточные данные на диск](/ru/reference/statements/select/group-by#group-by-in-external-memory). Агрегации с группировкой по префиксу первичного ключа особенно эффективны и часто выполняются с минимальным потреблением памяти.

<div id="execution-model">
  #### Модель выполнения
</div>

Описанные выше различия объясняются моделями выполнения Elasticsearch и ClickHouse, в основе которых лежат принципиально разные подходы к выполнению запросов и параллелизму.

ClickHouse спроектирован так, чтобы максимально эффективно использовать современное оборудование. По умолчанию ClickHouse выполняет SQL-запрос с N параллельными потоками выполнения на машине с N ядрами CPU:

<Image img="https://mintcdn.com/private-7c7dfe99-fix-nav-issues/0q6iTuCC0qup5NC4/images/use-cases/observability/clickhouse-execution.png?fit=max&auto=format&n=0q6iTuCC0qup5NC4&q=85&s=d5075ee7f241ff159671bf7de02b7d4a" alt="Выполнение ClickHouse" size="lg" width="1614" height="658" data-path="images/use-cases/observability/clickhouse-execution.png" />

На одном узле потоки выполнения разделяют данные на независимые диапазоны, что позволяет обрабатывать их параллельно в потоках CPU. Это включает фильтрацию, агрегацию и сортировку. Локальные результаты из каждого потока затем объединяются, после чего применяется оператор LIMIT, если он указан в запросе.

Выполнение запросов дополнительно распараллеливается за счет:

1. **SIMD-векторизации**: операции над столбцовыми данными используют [SIMD-инструкции CPU](https://en.wikipedia.org/wiki/Single_instruction,_multiple_data) (например, [AVX512](https://en.wikipedia.org/wiki/AVX-512)), что позволяет обрабатывать значения батчами.
2. **Параллелизма на уровне кластера**: в распределенных конфигурациях каждый узел выполняет обработку запросов локально. [Промежуточные состояния агрегации](https://clickhouse.com/blog/aggregate-functions-combinators-in-clickhouse-for-arrays-maps-and-states#working-with-aggregation-states) потоково передаются на инициирующий узел и объединяются. Если ключи `GROUP BY` в запросе совпадают с ключами сегментирования, слияние можно [свести к минимуму или полностью избежать](/ru/reference/settings/session-settings#distributed_group_by_no_merge).

<br />

Эта модель обеспечивает эффективное масштабирование по ядрам и узлам, благодаря чему ClickHouse хорошо подходит для крупномасштабной аналитики. Использование *промежуточных состояний агрегации* позволяет объединять промежуточные результаты из разных потоков и узлов без потери точности.

Elasticsearch, напротив, назначает один поток на сегмент для большинства агрегаций независимо от того, сколько ядер CPU доступно. Эти потоки возвращают локальные для сегмента результаты top-N, которые затем объединяются на координирующем узле. Такой подход может не в полной мере задействовать системные ресурсы и приводить к неточностям в глобальных агрегациях, особенно когда часто встречающиеся термины распределены по нескольким сегментам. Точность можно повысить, увеличив параметр `shard_size`, но это приводит к росту использования памяти и задержек при выполнении запросов.

<Image img="https://mintcdn.com/private-7c7dfe99-fix-nav-issues/FZqG0tBuMc0GoOY1/images/use-cases/observability/elasticsearch-execution.png?fit=max&auto=format&n=FZqG0tBuMc0GoOY1&q=85&s=c5ed329316240ad814062953fee1176a" alt="Выполнение Elasticsearch" size="lg" width="1606" height="784" data-path="images/use-cases/observability/elasticsearch-execution.png" />

Итог: ClickHouse выполняет агрегации и запросы с более мелкозернистым параллелизмом и более гибким управлением аппаратными ресурсами, тогда как Elasticsearch опирается на выполнение на основе сегментов с более жесткими ограничениями.

Чтобы подробнее разобраться в механике агрегаций в этих технологиях, рекомендуем запись в блоге ["ClickHouse vs. Elasticsearch: The Mechanics of Count Aggregations"](https://clickhouse.com/blog/clickhouse_vs_elasticsearch_mechanics_of_count_aggregations#elasticsearch).

<div id="data-management">
  ### Управление данными
</div>

Elasticsearch и ClickHouse используют принципиально разные подходы к управлению данными временных рядов для обсервабилити — в частности, в вопросах хранения данных, ролловера и многоуровневого хранения.

<div id="lifecycle-vs-ttl">
  #### Управление жизненным циклом индекса vs встроенный TTL
</div>

В Elasticsearch долгосрочное управление данными осуществляется с помощью **Index Lifecycle Management (ILM)** и **Data Streams**. Эти возможности позволяют задавать политики, определяющие, когда выполняется rollover индексов (например, по достижении определённого размера или возраста), когда старые индексы переносятся в более дешёвое хранилище (например, на тёплый или холодный уровень) и когда они в конечном итоге удаляются. Это необходимо, потому что Elasticsearch **не поддерживает повторное разбиение на сегменты**, а сегменты не могут расти бесконечно без ухудшения производительности. Чтобы контролировать размер сегментов и обеспечивать эффективное удаление, нужно периодически создавать новые индексы и удалять старые — то есть фактически выполнять ротацию данных на уровне индекса.

ClickHouse использует другой подход. Данные обычно хранятся в **одной таблице** и управляются с помощью **TTL-выражений (time-to-live)** на уровне столбца или партиции. Данные можно **партиционировать по дате**, что позволяет эффективно удалять их без необходимости создавать новые таблицы или выполнять rollover индексов. По мере устаревания данных и выполнения условия TTL ClickHouse автоматически удаляет их — для управления ротацией не требуется никакой дополнительной инфраструктуры.

<div id="storage-tiers">
  #### Уровни хранения и архитектуры hot-warm
</div>

Elasticsearch поддерживает архитектуры хранения **hot-warm-cold-frozen**, в которых данные перемещаются между уровнями хранения с разными характеристиками производительности. Обычно это настраивается через ILM и привязывается к ролям узлов в кластере.

ClickHouse поддерживает **многоуровневое хранение** с помощью нативных движков таблиц, таких как `MergeTree`, которые могут автоматически перемещать старые данные между разными **томами** (например, с SSD на HDD, а затем в Объектное хранилище) по заданным правилам. Это позволяет реализовать подход Elastic с hot-warm-cold — но без сложностей, связанных с управлением несколькими ролями узлов или кластерами.

<Info>
  **ClickHouse Cloud**

  В **ClickHouse Cloud** это работает еще проще: все данные хранятся в **Объектном хранилище (например, S3)**, а вычислительные ресурсы отделены от хранения. Данные могут оставаться в объектном хранилище до момента запроса, после чего они загружаются и кэшируются локально (или в распределенном кэше), обеспечивая тот же профиль затрат, что и frozen-уровень в Elastic, но с более высокой производительностью. При таком подходе данные не нужно перемещать между уровнями хранения, поэтому архитектуры hot-warm становятся избыточными.
</Info>

<div id="rollups-vs-incremental-aggregates">
  ### Rollups и инкрементальные агрегации
</div>

В Elasticsearch **rollups** или **агрегации** реализуются с помощью механизма [**transforms**](https://www.elastic.co/guide/en/elasticsearch/reference/current/transforms.html). Они используются для суммирования данных time-series через фиксированные интервалы (например, каждый час или каждый день) по модели **sliding window**. Они настраиваются как периодически выполняемые фоновые задачи, которые агрегируют данные из одного индекса и записывают результаты в отдельный **rollup index**. Это помогает снизить стоимость запросов на больших временных диапазонах, избавляя от повторного сканирования сырых данных с высокой кардинальностью.

Следующая диаграмма схематично показывает, как работают transforms (обратите внимание, что мы используем синий цвет для всех документов, принадлежащих одному и тому же бакету, для которого хотим заранее вычислить агрегированные значения):

<Image img="https://mintcdn.com/private-7c7dfe99-fix-nav-issues/FZqG0tBuMc0GoOY1/images/use-cases/observability/es-transforms.png?fit=max&auto=format&n=FZqG0tBuMc0GoOY1&q=85&s=e637c0099fa583d5a4336013de8a550f" alt="Трансформации Elasticsearch" size="lg" width="2750" height="1390" data-path="images/use-cases/observability/es-transforms.png" />

Непрерывные transforms используют [checkpoints](https://www.elastic.co/guide/en/elasticsearch/reference/current/transform-checkpoints.html), основанные на настраиваемом интервале проверки (параметр transform [frequency](https://www.elastic.co/guide/en/elasticsearch/reference/current/put-transform.html), значение по умолчанию — 1 минута). На диаграмме выше мы предполагаем, что ① после истечения интервала проверки создается новый checkpoint. Затем Elasticsearch проверяет наличие изменений в исходном индексе transform и обнаруживает три новых документа `blue` (11, 12 и 13), появившихся с момента предыдущего checkpoint. Поэтому исходный индекс фильтруется по всем существующим документам `blue`, и с помощью [composite aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-composite-aggregation.html) (чтобы использовать [pagination](https://www.elastic.co/guide/en/elasticsearch/reference/current/paginate-search-results.html) результатов) агрегированные значения пересчитываются заново (а индекс назначения обновляется документом, который заменяет документ с предыдущими значениями агрегации). Аналогично в точках ② и ③ новые checkpoints обрабатываются путем проверки изменений и пересчета агрегированных значений по всем существующим документам, принадлежащим одному и тому же бакету `blue`.

ClickHouse использует принципиально иной подход. Вместо периодической повторной агрегации данных ClickHouse поддерживает **incremental materialized views**, которые преобразуют и агрегируют данные **во время вставки**. Когда новые данные записываются в исходную таблицу, materialized view выполняет заранее определенный SQL-запрос агрегации только для новых **вставленных блоков** и записывает агрегированные результаты в целевую таблицу.

Эта модель возможна благодаря поддержке в ClickHouse [**Промежуточных состояний агрегации**](/ru/reference/data-types/aggregatefunction) — промежуточных представлений функций агрегации, которые можно хранить и затем объединять. Это позволяет поддерживать частично агрегированные результаты, которые быстро запрашиваются и недорого обновляются. Поскольку агрегация происходит по мере поступления данных, нет необходимости запускать дорогостоящие периодические задачи или заново агрегировать старые данные.

Ниже мы схематично показываем, как работают incremental materialized views (обратите внимание, что мы используем синий цвет для всех строк, принадлежащих одной и той же группе, для которой хотим заранее вычислить агрегированные значения):

<Image img="https://mintcdn.com/private-7c7dfe99-fix-nav-issues/0q6iTuCC0qup5NC4/images/use-cases/observability/ch-mvs.png?fit=max&auto=format&n=0q6iTuCC0qup5NC4&q=85&s=0de36c7773655b314ef17bb78d85aacb" alt="Materialized Views ClickHouse" size="lg" width="2224" height="2200" data-path="images/use-cases/observability/ch-mvs.png" />

На диаграмме выше исходная таблица materialized view уже содержит часть данных, в которой хранятся некоторые строки `blue` (с 1 по 10), принадлежащие одной и той же группе. Для этой группы в целевой таблице представления также уже существует часть данных, хранящая [Промежуточное состояние агрегации](https://www.youtube.com/watch?v=QDAJTKZT8y4) для группы `blue`. Когда происходят вставки ① ② ③ в исходную таблицу с новыми строками, для каждой вставки создается соответствующая часть данных исходной таблицы, и **параллельно**, только для каждого блока вновь вставленных строк, вычисляется промежуточное состояние агрегации и вставляется в виде части данных в целевую таблицу materialized view. ④ Во время фоновых слияний частей промежуточные состояния агрегации объединяются, что приводит к инкрементальной агрегации данных.

Обратите внимание, что все [агрегатные функции](/ru/reference/functions/aggregate-functions/reference-index) (их более 90), включая их комбинации с [combinators](https://www.youtube.com/watch?v=7ApwD0cfAFI) агрегатных функций, поддерживают [Промежуточные состояния агрегации](/ru/reference/data-types/aggregatefunction).

Более конкретный пример сравнения Elasticsearch и ClickHouse для инкрементальных агрегаций см. в этом [примере](https://github.com/ClickHouse/examples/tree/main/blog-examples/clickhouse-vs-elasticsearch/continuous-data-transformation#continuous-data-transformation-example).

Преимущества подхода ClickHouse включают:

* **Всегда актуальные агрегаты**: materialized view всегда остаются синхронизированными с исходной таблицей.
* **Без фоновых задач**: агрегации выполняются на этапе вставки, а не во время выполнения запроса.
* **Лучшая производительность в реальном времени**: идеально подходит для рабочих нагрузок обсервабилити и Real-time аналитики, где свежие агрегаты нужны мгновенно.
* **Комбинируемость**: materialized view можно выстраивать слоями или объединять через JOIN с другими представлениями и таблицами для более сложных стратегий ускорения запросов.
* **Разные TTL**: для исходной таблицы и целевой таблицы materialized view можно задавать разные настройки TTL.

Эта модель особенно эффективна для сценариев обсервабилити, где нужно вычислять метрики, такие как поминутная частота ошибок, задержки или разбиения top-N, не сканируя миллиарды сырых записей для каждого запроса.

<div id="lakehouse-support">
  ### Поддержка lakehouse
</div>

ClickHouse и Elasticsearch используют принципиально разные подходы к интеграции с lakehouse. ClickHouse — это полноценный движок выполнения запросов, который может выполнять запросы к форматам lakehouse, таким как [Iceberg](/ru/reference/functions/table-functions/iceberg) и [Delta Lake](/ru/reference/functions/table-functions/deltalake), а также интегрироваться с каталогами озер данных, такими как [AWS Glue](/ru/guides/use-cases/data-warehousing/glue-catalog) и [Unity catalog](/ru/guides/use-cases/data-warehousing/unity-catalog). Эти форматы опираются на эффективную обработку файлов [Parquet](/ru/reference/formats/Parquet/Parquet), которую ClickHouse полностью поддерживает. ClickHouse может напрямую читать таблицы Iceberg и Delta Lake, обеспечивая бесшовную интеграцию с современными архитектурами озер данных.

В отличие от этого, Elasticsearch тесно связан со своим внутренним форматом данных и движком хранения на базе Lucene. Он не может напрямую выполнять запросы к форматам lakehouse или файлам Parquet, что ограничивает его применимость в современных архитектурах озер данных. Прежде чем данные можно будет запрашивать в Elasticsearch, их необходимо преобразовать и загрузить в его проприетарный формат.

Возможности ClickHouse для работы с lakehouse выходят далеко за рамки простого чтения данных:

* **Интеграция с каталогом данных**: ClickHouse поддерживает интеграцию с каталогами данных, такими как [AWS Glue](/ru/guides/use-cases/data-warehousing/glue-catalog), что позволяет автоматически обнаруживать таблицы в объектном хранилище и получать к ним доступ.
* **Поддержка объектного хранилища**: нативная поддержка запросов к данным, хранящимся в [S3](/ru/reference/engines/table-engines/integrations/s3), [GCS](/ru/reference/functions/table-functions/gcs) и [Azure Blob Storage](/ru/reference/engines/table-engines/integrations/azureBlobStorage), без необходимости перемещения данных.
* **Федерация запросов**: возможность коррелировать данные из нескольких источников, включая таблицы lakehouse, традиционные базы данных и таблицы ClickHouse, с помощью [внешних словарей](/ru/concepts/features/dictionaries) и [табличных функций](/ru/reference/functions/table-functions).
* **Инкрементальная загрузка**: поддержка непрерывной загрузки из таблиц lakehouse в локальные таблицы [MergeTree](/ru/reference/engines/table-engines/mergetree-family/mergetree) с использованием таких возможностей, как [S3Queue](/ru/reference/engines/table-engines/integrations/s3queue) и [ClickPipes](/ru/integrations/clickpipes/home).
* **Оптимизация производительности**: выполнение распределённого запроса к данным lakehouse с помощью [cluster functions](/ru/reference/functions/table-functions/cluster) для повышения производительности.

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