Перейти к основному содержимому
Перейти к основному содержимому

Интеграция OpenTelemetry для сбора данных

Любое решение по обеспечению требует средства для сбора и экспорта логов и трасс. Для этой цели ClickHouse рекомендует проект OpenTelemetry (OTel).

"OpenTelemetry — это фреймворк и набор инструментов для обеспечения, созданный для создания и управления телеметрическими данными, такими как трассы, метрики и логи."

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

Важные компоненты ClickHouse

OpenTelemetry состоит из ряда компонентов. Кроме предоставления спецификации данных и API, стандартизированного протокола и наименований полей/колонок, OTel предоставляет две возможности, которые являются фундаментальными для создания решения по обеспечению с ClickHouse:

  • OpenTelemetry Collector — это прокси, который принимает, обрабатывает и экспортирует телеметрические данные. Решение, основанное на ClickHouse, использует этот компонент как для сбора логов, так и для обработки событий перед пакетированием и вставкой.
  • Языковые SDK, которые реализуют спецификацию, API и экспорт телеметрических данных. Эти SDK эффективно обеспечивают правильную запись трасс в коде приложения, генерируя составные охваты и обеспечивая распространение контекста через метаданные — таким образом формируя распределенные трассы и обеспечивая связь охватов. Эти SDK дополняются экосистемой, которая автоматически реализует общие библиотеки и фреймворки, таким образом пользователь не обязан изменять свой код и получает готовую инструментовку.

Решение по обеспечению на базе ClickHouse использует оба этих инструмента.

Дистрибуции

OpenTelemetry collector имеет несколько дистрибуций. Получатель filelog вместе с экспортёром ClickHouse, необходимый для решения ClickHouse, присутствует только в OpenTelemetry Collector Contrib Distro.

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

  • Уменьшить размер коллектора, сокращая время развертывания.
  • Улучшить безопасность коллектора, уменьшая доступную площадь атаки.

Создание пользовательского коллектора можно осуществить с помощью OpenTelemetry Collector Builder.

Сбор данных с OTel

Роли развертывания коллектора

Для сбора логов и вставки их в ClickHouse мы рекомендуем использовать OpenTelemetry Collector. OpenTelemetry Collector может быть развернут в двух основных ролях:

  • Агент — экземпляры агента собирают данные на краю, например, на серверах или на узлах Kubernetes, или получают события непосредственно от приложений — инструментированных с помощьюSDK OpenTelemetry. В последнем случае экземпляр агента работает с приложением или на том же хосте, что и приложение (например, как сайдкар или DaemonSet). Агенты могут отправлять свои данные напрямую в ClickHouse или на экземпляр шлюза. В первом случае это называется шаблон развертывания агента.
  • Шлюз — экземпляры шлюзов обеспечивают независимый сервис (например, развертывание в Kubernetes), обычно по кластеру, по центру обработки данных или по региону. Эти экземпляры получают события от приложений (или других коллекторов как агенты) через одну конечную точку OTLP. Обычно развертывается набор экземпляров шлюзов, с готовым балансировщиком нагрузки для распределения нагрузки между ними. Если все агенты и приложения отправляют свои сигналы на эту единую конечную точку, это часто называется шаблоном развертывания шлюза.

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

Сбор логов

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

Коллектор использует термины receiver, processor и exporter для своих трех основных этапов обработки. Приемники используются для сбора данных и могут быть реализованы как по принципу Pull, так и Push. Процессоры предоставляют возможность выполнять преобразования и обогащение сообщений. Экспортёры отвечают за отправку данных в downstream-сервис. Хотя этот сервис теоретически может быть другим коллектором, мы предполагаем, что все данные отправляются напрямую в ClickHouse для первоначального обсуждения ниже.

НУЖНО ALT

Мы рекомендуем пользователям ознакомиться с полным набором приемников, процессоров и экспортёров.

Коллектор предоставляет два основных приемника для сбора логов:

Через OTLP — В этом случае логи отправляются (передаются) непосредственно к коллектору из OpenTelemetry SDK через протокол OTLP. Демо OpenTelemetry использует этот подход, при этом экспортёры OTLP для каждого языка предполагают конечную точку локального коллектора. Коллектор в этом случае должен быть настроен с приемником OTLP — смотрите выше демо для конфигурации. Преимущество этого подхода заключается в том, что данные логов будут автоматически содержать идентификаторы трасс, позволяя пользователям позже идентифицировать трассы для конкретного лога и наоборот.

НУЖНО ALT

Этот подход требует от пользователей инструментирования их кода с использованием соответствующего языкового SDK.

  • Сканирование через приемник filelog — Этот приемник отслеживает файлы на диске и формирует сообщения логов, отправляя их в ClickHouse. Этот приемник обрабатывает сложные задачи, такие как обнаружение многострочных сообщений, управление прокруткой логов, создание контрольных точек для надежности при перезапуске и извлечение структуры. Этот приемник также способен отслеживать логи контейнеров Docker и Kubernetes, развертываемый в качестве хелм-диаграммы, извлекая структуру из них и обогащая их деталями пода.
НУЖНО ALT

Большинство развертываний будут использовать комбинацию вышеуказанных приемников. Мы рекомендуем пользователям ознакомиться с документацией коллектора и ознакомиться с основными концепциями, наряду с структурой конфигурации и методами установки.

примечание
Совет: otelbin.io

otelbin.io полезен для проверки и визуализации конфигураций.

Структурированные против неструктурированных

Логи могут быть структурированными или неструктурированными.

Структурированный лог будет использовать формат данных, такой как JSON, определяющий метаданные, такие как код http и адрес источника IP.

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

Мы рекомендуем пользователям использовать структурированное логирование и логировать в формате JSON (т.е. ndjson), когда это возможно. Это упростит требуемую обработку логов позже, либо перед отправкой в ClickHouse с помощью процессоров Collector, либо в момент вставки с использованием материальных представлений. Структурированные логи в конечном итоге сэкономят ресурсы на последующей обработке, уменьшая необходимую загрузку процессора в вашем решении ClickHouse.

Пример

Для примера мы предоставляем набор данных с структурированным (JSON) и неструктурированным логированием, каждый из которых содержит примерно 10 млн строк, доступных по следующим ссылкам:

Мы используем структурированный набор данных для примера ниже. Убедитесь, что этот файл загружен и извлечен, чтобы воспроизвести следующие примеры.

Следующее представляет собой простую конфигурацию для OTel Collector, который читает эти файлы на диске, используя приемник filelog, и выводит полученные сообщения в stdout. Мы используем оператор json_parser, так как наши логи структурированы. Измените путь к файлу access-structured.log.

Рассмотрите ClickHouse для разбора

Ниже приведенный пример извлекает временную метку из лога. Это требует использования оператора json_parser, который конвертирует всю строку лога в строку JSON, помещая результат в LogAttributes. Это может быть вычислительно затратным и может быть выполнено более эффективно в ClickHouse - Извлечение структуры с помощью SQL. Эквивалентный неструктурированный пример, который использует regex_parser для достижения этого, можно найти здесь.

config-structured-logs.yaml

Пользователи могут следовать официальным инструкциям для установки коллектора локально. Важно, чтобы инструкции были изменены для использования дистрибуции contrib (которая содержит приемник filelog), например, вместо otelcol_0.102.1_darwin_arm64.tar.gz пользователи должны загрузить otelcol-contrib_0.102.1_darwin_arm64.tar.gz. Релизы можно найти здесь.

После установки OTel Collector можно запустить с помощью следующих команд:

Предполагая использование структурированных логов, сообщения примут следующую форму на выводе:

Выше представлено одно сообщение лога, сгенерированное OTel collector. Мы импортируем эти же сообщения в ClickHouse в следующих разделах.

Полная схема сообщений логов, наряду с дополнительными колонками, которые могут присутствовать при использовании других приемников, поддерживается здесь. Мы настоятельно рекомендуем пользователям ознакомиться с этой схемой.

Ключевым моментом здесь является то, что сама строка лога хранится как строка внутри поля Body, но JSON был автоматически извлечен в поле Attributes благодаря json_parser. Тот же оператор использовался для извлечения временной метки в соответствующий столбец Timestamp. Для рекомендаций по обработке логов с OTel смотрите Обработка.

Операторы

Операторы являются самой базовой единицей обработки логов. Каждый оператор выполняет одну функцию, такую как чтение строк из файла или парсинг JSON из поля. Операторы затем связываются вместе в конвейере для достижения желаемого результата.

Вышеупомянутые сообщения не имеют поля TraceID или SpanID. Если они присутствуют, например в случаях, когда пользователи реализуют распределенное трассирование, их можно извлечь из JSON с использованием тех же техник, что и показано выше.

Для пользователей, которым необходимо собирать локальные или Kubernetes лог-файлы, мы рекомендуем ознакомиться с параметрами конфигурации, доступными для приемника filelog и как offsets и разбор многострочных логов обрабатывается.

Сбор логов Kubernetes

Для сбора логов Kubernetes мы рекомендуем руководствоваться документацией Open Telemetry. Рекомендуется использовать Kubernetes Attributes Processor для обогащения логов и метрик метаданными пода. Это может потенциально производить динамические метаданные, например, метки, хранящиеся в колонке ResourceAttributes. ClickHouse в настоящее время использует тип Map(String, String) для этой колонки. См. Использование карт и Извлечение из карт для получения дополнительных сведений об обработке и оптимизации этого типа.

Сбор трасс

Для пользователей, желающих инструментировать свой код и собирать трассы, мы рекомендуем следовать официальной документации OTel.

Чтобы доставить события в ClickHouse, пользователям потребуется развернуть OTel collector для приема событий трассы по протоколу OTLP через соответствующий приемник. Демонстрация OpenTelemetry предоставляет пример инструментирования каждого поддерживаемого языка и отправки событий в коллектор. Пример соответствующей конфигурации коллектора, который выводит события в stdout, показан ниже:

Пример

Поскольку трассы должны быть получены через OTLP, мы используем инструмент telemetrygen для генерации данных трасс. Следуйте инструкциям здесь для установки.

Следующая конфигурация получает события трассы на приемнике OTLP перед отправкой их в stdout.

config-traces.xml

Запустите эту конфигурацию с помощью:

Отправьте события трассы на коллектор через telemetrygen:

Это приведет к получению сообщений трасс, подобных следующему примеру, на выводе:

Выше представлено одно сообщение трассы, сгенерированное OTel collector. Мы импортируем эти же сообщения в ClickHouse в следующих разделах.

Полная схема сообщений трасс поддерживается здесь. Мы настоятельно рекомендуем пользователям ознакомиться с этой схемой.

Обработка - фильтрация, преобразование и обогащение

Как показано в более раннем примере установки временной метки для события лога, пользователи в конечном счете захотят фильтровать, преобразовывать и обогащать сообщения событий. Это можно сделать с помощью ряда возможностей в Open Telemetry:

  • Процессоры — Процессоры принимают данные, собранные приемниками и модифицируют или преобразовывают их, прежде чем отправить их экспортёрам. Процессоры применяются в порядке, установленном в разделе processors конфигурации коллектора. Эти процессоры необязательны, но рекомендуется минимальный набор обычно. При использовании OTel collector с ClickHouse мы рекомендуем ограничить процессоры:

    • memory_limiter используется для предотвращения ситуаций с недостатком памяти на коллекторе. См. Оценка ресурсов для рекомендаций.
    • Любой процессор, который выполняет обогащение на основе контекста. Например, Kubernetes Attributes Processor позволяет автоматическую установку атрибутов ресурсов для охватов, метрик и логов с метаданными k8s, например, обогащение событий их идентификатором пода источника.
    • Выборка с хвоста или головы при необходимости для трасс.
    • Основная фильтрация — исчезновение событий, которые не требуются, если это нельзя сделать через оператор (см. ниже).
    • Пакетирование — необходимо при работе с ClickHouse, чтобы гарантировать, что данные отправляются пакетами. См. "Экспорт в ClickHouse".
  • ОператорыОператоры представляют собой самую базовую единицу обработки, доступную на приемнике. Поддерживается базовый парсинг, позволяя устанавливать такие поля, как Степень и Временная метка. Здесь поддерживается парсинг JSON и регулярных выражений, а также фильтрация событий и базовые преобразования. Мы рекомендуем выполнять фильтрацию событий здесь.

Мы рекомендуем пользователям избегать чрезмерной обработки событий с помощью операторов или преобразовательных процессоров. Эти операции могут приводить к значительным затратам по памяти и загрузке процессора, особенно при парсинге JSON. Возможна вся обработка в ClickHouse в момент вставки с использованием материальных представлений и колонок с некоторыми исключениями — особенно, обогащение, требующее контекста, например, добавление метаданных k8s. Для получения более подробной информации смотрите Извлечение структуры с помощью SQL.

Если обработка выполняется с помощью OTel collector, мы рекомендуем выполнять преобразования на экземплярах шлюзов и минимизировать любые работы на экземплярах агентов. Это обеспечит минимальные ресурсы, необходимые агентам на краю, работающим на серверах. Обычно мы видим, что пользователи выполняют только фильтрацию (для минимизации ненужного сетевого трафика), установку временной метки (через операторов) и обогащение, требующее контекста, на агентах. Например, если экземпляры шлюзов находятся в другом кластере Kubernetes, обогащение k8s должно происходить в агенте.

Пример

Следующая конфигурация показывает сбор неструктурированного лог-файла. Обратите внимание на использование операторов для извлечения структуры из строк логов (regex_parser) и фильтрации событий, вместе с процессором для пакетирования событий и ограничения использования памяти.

config-unstructured-logs-with-processor.yaml

Экспорт в ClickHouse

Экспортеры отправляют данные в один или несколько бэкендов или назначений. Экспортеры могут быть основаны на методах "pull" или "push". Для отправки событий в ClickHouse пользователи должны использовать основанный на методе push экспортер ClickHouse.

Используйте OpenTelemetry Collector Contrib

Экспортер ClickHouse является частью OpenTelemetry Collector Contrib, а не основной дистрибуции. Пользователи могут либо использовать дистрибуцию contrib, либо собрать свой собственный collector.

Полный файл конфигурации представлен ниже.

clickhouse-config.yaml

Обратите внимание на следующие ключевые настройки:

  • pipelines - Вышеприведенная конфигурация подчеркивает использование pipelines, состоящих из набора получателей, обработчиков и экспортеров для логов и трассировок.
  • endpoint - Связь с ClickHouse настраивается с помощью параметра endpoint. Строка подключения tcp://localhost:9000?dial_timeout=10s&compress=lz4&async_insert=1 создает соединение через TCP. Если пользователи предпочитают HTTP по причинам переключения трафика, измените эту строку подключения, как описано здесь. Полные детали соединения, с возможностью указания имени пользователя и пароля в этой строке подключения, описаны здесь.

Важно: Обратите внимание, что указанная выше строка подключения позволяет включить как сжатие (lz4), так и асинхронные вставки. Мы рекомендуем всегда включать оба. Смотрите Batching для получения дополнительной информации об асинхронных вставках. Сжатие всегда должно быть указано и не будет включено по умолчанию в более старых версиях экспортера.

  • ttl - значение здесь определяет, как долго данные сохраняются. Дополнительные детали приведены в "Управление данными". Это должно быть указано в виде единицы времени в часах, например, 72h. В примере ниже мы отключаем TTL, поскольку наши данные из 2019 года будут немедленно удалены ClickHouse, если будут вставлены.
  • traces_table_name и logs_table_name - определяют имя таблицы логов и трассировок.
  • create_schema - определяет, создаются ли таблицы с использованием схем по умолчанию при запуске. По умолчанию установлено значение true для удобства начала работы. Пользователи должны установить это значение в false и определить свою собственную схему.
  • database - целевая база данных.
  • retry_on_failure - настройки для определения, должны ли неудачные партии повторяться.
  • batch - обработчик пакетов гарантирует, что события отправляются пакетами. Мы рекомендуем значение около 5000 с тайм-аутом 5s. То, что будет достигнуто первым, инициирует сброс пакета в экспортер. Понижение этих значений приведет к меньшей задержке в конвейере, с данными, доступными для запросов быстрее, за счет большего количества соединений и пакетов, отправленных в ClickHouse. Это не рекомендуется, если пользователи не используют асинхронные вставки, так как это может вызвать проблемы с слишком большим количеством частей в ClickHouse. Напротив, если пользователи используют асинхронные вставки, доступность данных для запросов также будет зависеть от настроек асинхронной вставки - хотя данные все равно будут сброшены из коннектора быстрее. Смотрите Batching для получения дополнительной информации.
  • sending_queue - контролирует размер очереди отправки. Каждый элемент в очереди содержит пакет. Если эта очередь превышается, например, из-за недоступности ClickHouse, но события продолжают приходить, пакеты будут отброшены.

Предполагая, что пользователи извлекли структурированный лог-файл и у них есть локальный экземпляр ClickHouse, запущенный (с аутентификацией по умолчанию), пользователи могут запустить эту конфигурацию с помощью команды:

Чтобы отправить трассировочные данные в этот коллектор, выполните следующую команду, используя инструмент telemetrygen:

После запуска подтвердите наличие событий в логах с помощью простого запроса:

Схема по умолчанию

По умолчанию экспортер ClickHouse создает целевую таблицу логов как для логов, так и для трассировок. Это можно отключить с помощью настройки create_schema. Кроме того, имена для таблиц логов и трассировок можно изменить с их значений по умолчанию otel_logs и otel_traces с помощью вышеупомянутых настроек.

примечание

В следующих схемах мы предполагаем, что TTL включен на уровне 72h.

Схема по умолчанию для логов представлена ниже (otelcol-contrib v0.102.1):

Колонки здесь соответствуют официальной спецификации OTel для логов, документированной здесь.

Несколько важных заметок о данной схеме:

  • По умолчанию таблица разделена по дате через PARTITION BY toDate(Timestamp). Это делает эффективным удаление данных, которые истекли.
  • TTL устанавливается через TTL toDateTime(Timestamp) + toIntervalDay(3) и соответствует значению, установленному в конфигурации коллектора. ttl_only_drop_parts=1 означает, что только целые части удаляются, когда все содержащиеся строки истекли. Это более эффективно, чем удаление строк внутри частей, что влечет за собой дорогую операцию удаления. Мы рекомендуем всегда устанавливать это значение. Смотрите Управление данными с TTL для получения дополнительной информации.
  • Таблица использует классический MergeTree engine. Это рекомендуется для логов и трассировок и, вероятно, не потребует изменений.
  • Таблица упорядочена по ORDER BY (ServiceName, SeverityText, toUnixTimestamp(Timestamp), TraceId). Это означает, что запросы будут оптимизированы для фильтров по ServiceName, SeverityText, Timestamp и TraceId - более ранние столбцы в списке будут фильтроваться быстрее, чем более поздние, например, фильтрация по ServiceName будет значительно быстрее, чем фильтрация по TraceId. Пользователи должны изменить этот порядок в соответствии с ожидаемыми шаблонами доступа - смотрите Выбор первичного ключа.
  • Указанная выше схема применяет ZSTD(1) к колонкам. Это предлагает лучшее сжатие для логов. Пользователи могут увеличить уровень сжатия ZSTD (выше значения по умолчанию 1) для лучшего сжатия, хотя это редко бывает выгодно. Увеличение этого значения приведет к большей нагрузке на процессор во время вставки (при сжатии), хотя время декомпрессии (а значит, и запросов) должно оставаться сопоставимым. Смотрите здесь для получения дополнительных сведений. Кроме того, к временной метке применяется delta encoding с целью уменьшить ее размер на диске.
  • Обратите внимание, как ResourceAttributes, LogAttributes и ScopeAttributes являются картами. Пользователи должны ознакомиться с разницей между этими типами. Для получения информации о том, как получить доступ к этим картам и оптимизировать доступ к ключам внутри них, смотрите Использование карт.
  • Большинство других типов, таких как ServiceName как LowCardinality, оптимизированы. Обратите внимание, что тело, хотя и является JSON в наших примерах логов, хранится как строка.
  • Фильтры Блума применяются к ключам и значениям карт, а также к колонке Body. Они направлены на улучшение времени запросов к этим колонкам, но обычно не являются обязательными. Смотрите Вторичные/Индексы для пропуска данных.

Вновь эта схема будет соответствовать колонкам, соответствующим официальной спецификации OTel для трассировок, документированной здесь. Схема содержит многие из тех же настроек, что и вышеописанная схема для логов, с дополнительными колонками Links, специфичными для спанов.

Мы рекомендуем пользователям отключить автоматическое создание схемы и создать свои таблицы вручную. Это позволяет изменить первичные и вторичные ключи, а также предоставляет возможность ввести дополнительные колонки для оптимизации производительности запросов. Для получения дополнительной информации смотрите Дизайн схемы.

Оптимизация вставок

Для достижения высокой производительности вставок при получении строгих гарантий согласованности пользователи должны придерживаться простых правил при вставке данных наблюдаемости в ClickHouse через коллектор. С правильной конфигурацией OTel collector следующие правила обычно легко соблюсти. Это также позволяет избежать распространенных проблем, с которыми пользователи сталкиваются при первом использовании ClickHouse.

Пакетирование

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

По умолчанию вставки в ClickHouse являются синхронными и идемпотентными, если идентичны. Для таблиц семейства движков merge tree ClickHouse по умолчанию автоматически удаляет дубликаты вставок. Это означает, что вставки допускаются в случаях, подобных следующим:

  • (1) Если узел, получающий данные, имеет проблемы, запрос на вставку истечет (или получит более конкретную ошибку) и не получит подтверждения.
  • (2) Если данные записаны узлом, но подтверждение не может быть возвращено отправителю запроса из-за сетевых нарушений, отправитель либо получит тайм-аут, либо сетевую ошибку.

С точки зрения коллектора, (1) и (2) могут быть трудно различимы. Однако в обоих случаях неподтвержденную вставку можно немедленно повторить. При условии, что повторяемый запрос на вставку содержит одни и те же данные в том же порядке, ClickHouse автоматически проигнорирует повторяемую вставку, если (неподтвержденная) оригинальная вставка была успешной.

Мы рекомендуем пользователям использовать обработчик пакетов, показанный в ранее упомянутых конфигурациях, чтобы удовлетворить вышеупомянутое. Это гарантирует, что вставки отправляются как последовательные пакеты строк, удовлетворяющие данным требованиям. Если ожидается, что коллектор будет иметь высокую пропускную способность (событий в секунду), и по меньшей мере 5000 событий могут быть отправлены в каждой вставке, это обычно единственное пакетирование, необходимое в конвейере. В этом случае коллектор будет сбрасывать пакеты до того, как истечет timeout обработчика пакетов, обеспечивая низкую задержку конца в конце конвейера и согласованный размер пакетов.

Используйте асинхронные вставки

Обычно пользователи вынуждены отправлять меньшие партии, когда пропускная способность коллектора низкая, и все же ожидают, что данные достигнут ClickHouse в пределах минимальной задержки. В этом случае отправляются небольшие пакеты, когда истекает timeout обработчика пакетов. Это может вызвать проблемы, и именно тогда требуются асинхронные вставки. Этот случай обычно возникает, когда коллекторы в роли агента настраиваются для отправки напрямую в ClickHouse. Шлюзы, действуя как агрегаторы, могут смягчить эту проблему - смотрите Масштабирование с помощью шлюзов.

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

NEEDS ALT

При включенных асинхронных вставках, когда ClickHouse ① получает запрос на вставку, данные запроса ② немедленно записываются в буфер в памяти. Когда ③ происходит следующий сброс буфера, данные буфера сортируются и записываются как часть в хранилище базы данных. Обратите внимание, что данные не могут быть доступны для запросов до того, как они будут сброшены в хранилище базы данных; сброс буфера конфигурируется.

Чтобы включить асинхронные вставки для коллектора, добавьте async_insert=1 в строку подключения. Мы рекомендуем пользователям использовать wait_for_async_insert=1 (по умолчанию) для гарантии доставки - смотрите здесь для получении дополнительных сведений.

Данные из асинхронной вставки вставляются, как только буфер ClickHouse сброшен. Это происходит либо после превышения async_insert_max_data_size, либо после async_insert_busy_timeout_ms миллисекунд с момента первого запроса INSERT. Если async_insert_stale_timeout_ms установлен на значение, отличное от нуля, данные вставляются после async_insert_stale_timeout_ms milliseconds с момента последнего запроса. Пользователи могут настроить эти параметры для контроля задержки конца в конце своего конвейера. Дополнительные параметры, которые можно использовать для настройки сброса буфера, документированы здесь. Как правило, значения по умолчанию подходят.

Учитывайте адаптивные асинхронные вставки

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

Наконец, предыдущее поведение удаления дубликатов, связанное с синхронными вставками в ClickHouse, по умолчанию не включается при использовании асинхронных вставок. Если это требуется, смотрите настройку async_insert_deduplicate.

Полные детали по настройке этой функции можно найти здесь, с углубленным изучением здесь.

Архитектуры развертывания

Существует несколько возможных архитектур развертывания при использовании OTel коллектора с ClickHouse. Мы описываем каждую из них ниже и когда они могут быть применены.

Только агенты

В архитектуре только агентов пользователи развертывают OTel collector в качестве агентов на краю. Эти агенты получают трассировки от локальных приложений (например, в качестве контейнера sidecar) и собирают логи с серверов и узлов Kubernetes. В этом режиме агенты отправляют свои данные напрямую в ClickHouse.

NEEDS ALT

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

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

  • Масштабирование подключений - Каждый агент будет устанавливать соединение с ClickHouse. Хотя ClickHouse способен поддерживать сотни (если не тысячи) одновременных подключений для вставки, это в конечном итоге станет ограничивающим фактором и снизит эффективность вставок - то есть ClickHouse будет использовать больше ресурсов на поддержание соединений. Использование шлюзов минимизирует количество соединений и делает вставки более эффективными.
  • Обработка на краю - Любые преобразования или обработка событий должны выполняться на краю или в ClickHouse в этой архитектуре. Это, наряду с тем, что это ограничительно, может означать сложные материализованные представления ClickHouse или перенесение значительных вычислений на край - где критические службы могут пострадать, а ресурсы могут быть ограничены.
  • Малые пакеты и задержки - Коллекторы-агенты могут собирать очень немного событий. Обычно это означает, что их необходимо настраивать для сброса с установленным интервалом, чтобы удовлетворять SLA доставки. Это может привести к тому, что коллектор будет отправлять небольшие пакеты в ClickHouse. Хотя это является недостатком, это можно смягчить с помощью асинхронных вставок - смотрите Оптимизация вставок.

Масштабирование с помощью шлюзов

OTel collectors могут быть развернуты в качестве экземпляров шлюзов для решения вышеупомянутых ограничений. Они предоставляют автономный сервис, обычно для каждого дата-центра или региона. Эти экземпляры принимают события от приложений (или других коллекторов в роли агента) через единую конечную точку OTLP. Обычно развертывается набор экземпляров шлюзов, с предустановленным балансировщиком нагрузки, используемым для распределения нагрузки между ними.

NEEDS ALT

Цель данной архитектуры состоит в том, чтобы разгрузить ресурсоемкие вычисления от агентов, тем самым минимизируя их использование ресурсов. Эти шлюзы могут выполнять задачи преобразования, которые иначе имели бы место выполняться агентами. Более того, агрегируя события от многих агентов, шлюзы могут гарантировать, что крупные партии будут отправлены в ClickHouse, что позволяет эффективно вставлять данные. Эти коллекторы шлюза могут легко масштабироваться по мере добавления новых агентов и увеличения пропускной способности событий. Пример конфигурации шлюза с ассоциированной конфигурацией агента, обрабатывающего пример структурированного лог-файла, показан ниже. Обратите внимание на использование OTLP для связи между агентом и шлюзом.

clickhouse-agent-config.yaml

clickhouse-gateway-config.yaml

Эти конфигурации можно запустить с помощью следующих команд.

Основным недостатком этой архитектуры является связанная с ней стоимость и накладные расходы на управление набором коллекторов.

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

Добавление Kafka

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

Использование очереди Kafka в качестве буфера сообщений является популярным шаблоном проектирования, наблюдаемым в архитектурах логирования, и был популяризирован стеком ELK. Он предоставляет несколько преимуществ; в первую очередь, он помогает обеспечить более сильные гарантии доставки сообщений и помогает справляться с обратным давлением. Сообщения отправляются от агентов сбора в Kafka и записываются на диск. Теоретически кластерный экземпляр Kafka должен обеспечивать высокую пропускную способность буфера сообщений, поскольку он требует меньше вычислительных ресурсов для записи данных линейно на диск, чем для разбора и обработки сообщения – в Elastic, например, токенизация и индексация требуют значительных ресурсов. Перемещая данные от агентов, вы также снижаете риск потери сообщений в результате ротации логов на источнике. Наконец, это предоставляет некоторые возможности для повторной доставки сообщений и репликации между регионами, что может быть привлекательно для некоторых случаев использования.

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

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

NEEDS ALT

В этом случае агенты OTel могут быть настроены на отправку данных в Kafka через Kafka exporter. Экземпляры шлюзов, в свою очередь, обрабатывают сообщения с помощью Kafka receiver. Мы рекомендуем обратиться к документации Confluent и OTel для получения дополнительных деталей.

Оценка ресурсов

Требования к ресурсам для OTel collector будут зависеть от пропускной способности событий, размера сообщений и объема выполняемой обработки. Проект OpenTelemetry поддерживает бенчмарки, которые пользователи могут использовать для оценки требований к ресурсам.

По нашему опыту, экземпляр шлюза с 3 ядрами и 12 ГБ оперативной памяти может обрабатывать около 60 000 событий в секунду. Это предполагает минимальный процессинговый конвейер, ответственный за переименование полей, и отсутствие регулярных выражений.

Для экземпляров агентов, отвечающих за отправку событий в шлюз и устанавливающих только временную метку события, мы рекомендуем пользователям рассчитывать ресурсы на основе предполагаемого количества логов в секунду. Следующие представляют собой приблизительные числа, которые пользователи могут использовать как отправную точку:

Скорость логирования Ресурсы для коллектора агента 1k/секунда 0.2CPU, 0.2GiB 5k/секунда 0.5 CPU, 0.5GiB 10k/секунда 1 CPU, 1GiB

Скорость логированияРесурсы для коллектора агента
1k/секунда0.2CPU, 0.2GiB
5k/секунда0.5 CPU, 0.5GiB
10k/секунда1 CPU, 1GiB