Масштабирование Collector

Материал из Документация Ключ-АСТРОМ

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

Более общую информацию в документации OpenTelemetry можно найти на странице «Масштабирование Collector» на веб-сайте OpenTelemetry.

Определение того, когда следует масштабировать

Вам следует рассмотреть возможность масштабирования, когда вы приблизитесь к пределам ресурсов, выделенных вашему Collector. Для отслеживания этого будут полезны метрики самоконтроля, доступные в Collector, и метрики, доступные в среде хоста (например, Kubernetes). Подробнее о сборе этих данных см. на нашей странице, посвященной самоконтролю Collector . Ниже приведены несколько метрик, на которые стоит обратить внимание:

  • otelcol_processor_refused_spans: Если у вас включен процессор-ограничитель памяти, эта метрика (или эквивалент для других сигналов) будет указывать на то, что Collector требуется больше памяти для продолжения обработки текущей нагрузки.
  • otelcol_exporter_queue_capacityи otelcol_exporter_queue_size: Когда размер очереди экспортера приближается к её ёмкости или превышает её, это означает, что у Collector возникают проблемы с отправкой данных на бэкенд. Это происходит либо из-за нехватки рабочих процессов для отправки данных, либо из-за перегрузки самого бэкенда. Возможно, вам потребуется увеличить вычислительную мощность Collector для продолжения обработки этого объёма данных.
  • k8s.resource_quota.used: Если вы отслеживаете свой кластер Kubernetes с помощью Kubernetes Cluster Receiver , это можно использовать для определения объема квоты ЦП/памяти, используемой вашим Collector.
  • container.cpu.usageи container.memory.usage: Если вы отслеживаете свой кластер с помощью Kubelet Stats Receiver , они могут сообщить вам, приближается ли конкретный контейнер Collector к пределам своей квоты или достигает их.

Масштабирование Collector

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

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

Масштабирование Collector без сохранения состояния

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

Самый простой способ балансировки нагрузки — использовать объект Kubernetes Service, который указывает на несколько реплик пода Collector, развёрнутого через любой стандартный тип рабочей нагрузки Kubernetes, такой как Deployment, ReplicaSet, StatefulSet или DaemonSet. Для кратковременных соединений это позволит распределить нагрузку между Collector, доступными через службу, достаточно равномерно. Обратите внимание, что долговременные соединения, например, по HTTP/2 или gRPC, будут поддерживать соединение с одним Collector и, следовательно, могут привести к неравномерному распределению нагрузки между Collector.

В более сложных случаях, таких как обработка подключений gRPC, служба с типом LoadBalancer может обеспечить больший контроль над балансировкой нагрузки. Службы LoadBalancer могут использовать отдельный балансировщик нагрузки для определения того, к какому Collector будет направлено соединение. Сервисные сети, такие как Istio или Linkerd, также могут помочь в балансировке нагрузки, поскольку они обеспечивают детальный контроль над сетевыми подключениями внутри кластера.

В случаях, когда топология развертывания имеет значение, например, при развертывании шлюзовых Collector через DaemonSet, вы можете использовать объект Service со специальными настройками маршрутизации, чтобы отправлять данные только Collector, работающим на том же узле, что и источник данных.Kubernetes версии 1.26+ это делается путем настройки службы на прием только внутреннего трафика узла.

Масштабирование обработки с сохранением состояния с использованием необъединенных Collector

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

  • Collector Sidecar : если Collector развернут как вспомогательный объект и связан с приложением, то все данные из этого приложения пройдут через Collector Sidecar и могут быть обработаны с помощью операций с отслеживанием состояния.
  • DaemonSet Collectors : агент Collector, развёрнутый на узле Kubernetes (например, через DaemonSet), может использоваться для обработки с отслеживанием состояния, если приложение на узле всегда отправляет свои данные в Collector. Обратите внимание, что это предполагает наличие только одного Collector на каждом узле.
  • Один Collector : если вам нужно запустить только один Collector для заданного набора источников данных, этот Collector можно использовать для обработки с отслеживанием состояния, поскольку все данные будут проходить через один и тот же Collector. Вы можете выбрать этот вариант, если решите отправлять определённый сигнал или данные из выбранного набора приложений на данный Collector. Обратите внимание, что для обеспечения высокой доступности избыточные экземпляры Collector должны храниться в качестве резервных копий и не получать данные, пока первый Collector не выйдет из строя. Кроме того, обработка будет сброшена при активации избыточного Collector.

Масштабирование объединенных в пул Collector с отслеживанием состояния с помощью Load Balancing Exporter

Масштабирование горизонтально масштабируемого пула Collector с отслеживанием состояния, вероятно, потребует использования экспортера балансировки нагрузки (Load Balancing Exporter). Экспортер балансировки нагрузки превращает Collector в балансировщик нагрузки с поддержкой OTLP, позволяющий направлять данные на конкретный нижестоящий Collector на основе информации из полезной нагрузки OTLP, например, имени метрики.

Процессоры с отслеживанием состояния

Вам следует рассмотреть возможность использования экспортера, если вы масштабируете данные и используете любой из следующих компонентов с отслеживанием состояния. Здесь мы рассматриваем только компоненты, входящие в состав Ключ-АСТРОМ Collector, вам необходимо определить оптимальное значение по умолчанию для всех остальных используемых компонентов с отслеживанием состояния. Вы также можете настроить, какая часть данных будет использоваться для маршрутизации. Оптимальный ключ для использования зависит от вашего варианта использования, но ниже мы приводим рекомендации.

  • Накопительные данные для дельта-процессора : точки данных для одной и той же метрики должны быть отправлены одному и тому же Collector за период сбора метрики metric_name. Таким образом, ключ является подходящим значением по умолчанию для маршрутизации.
  • Процессор выборки хвоста : Чтобы принять решение о выборке трассировки, процессор должен иметь возможность видеть все интервалы внутри трассировки. Следовательно, все интервалы должны быть отправлены одному и тому же Collector, и для этого мы рекомендуем маршрутизацию по ключу traceID.
  • Коннектор метрик Span : Коннектору необходимо видеть все интервалы сервиса, чтобы выдавать метрики его производительности. Поэтому мы настоятельно рекомендуем маршрутизацию по ключу service.

Настройка экспортера балансировки нагрузки

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

Настройка ключа маршрутизации осуществляется путем установки параметра routing_key. Значения по умолчанию для каждого сигнала:

  • Трассировки: traceID
  • Метрики: service
  • Логи: traceID если есть, в противном случае — случайный идентификатор трассировки. Параметр routing_key не переопределяет это поведение и не влияет на маршрутизацию логов.

Мы рекомендуем вам оставить их значениями по умолчанию или настроить их на основе рекомендаций, приведенных выше в разделе «Процессоры с отслеживанием состояния» .

Другой важный параметр конфигурации — это ключ resolver, который используется экспортером для определения доступных для пересылки данных Collector. В Kubernetes мы рекомендуем использовать резольвер k8s, поскольку он является нативным для Kubernetes. В частности, он поддерживает динамическое обновление пула в зависимости от запущенных подов Collector и добавляет или удаляет Collector при изменении количества реплик. Он также удаляет Collector, которые становятся неработоспособными, обеспечивая выполнение требований высокой доступности, если повторные попытки также настроены с помощью параметра retry_on_failure.

Устойчивость

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

Масштабирование балансировщика нагрузки Collector

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

Демо конфигурация

extensions:

  health_check:

    endpoint: 0.0.0.0:13133

receivers:

  otlp:

    protocols:

      grpc:

        endpoint: 0.0.0.0:4317

      http:

        endpoint: 0.0.0.0:4318

exporters:

  loadbalancing/traces:

    protocol:

      otlp:

    resolver:

      k8s:

        service: traces-receiver.default

        ports:

          - 4317

  loadbalancing/logs:

    protocol:

      otlp:

    resolver:

      k8s:

        service: logs-receiver.default

        ports:

          - 4317

  loadbalancing/metrics:

    retry_on_failure:

      enabled: true

      initial_interval: 5s

      max_interval: 30s

      max_elapsed_time: 300s

    sending_queue:

      enabled: true

      num_consumers: 10

      queue_size: 1000

      sizer: requests

    protocol:

      otlp:

    resolver:

      k8s:

        service: metrics-receiver.default

        ports:

          - 4317

service:

  extensions: [health_check]

  pipelines:

    metrics:

      receivers: [otlp]

      processors: []

      exporters:

        - loadbalancing/metrics

    traces:

      receivers: [otlp]

      processors: []

      exporters:

        - loadbalancing/traces

    logs:

      receivers: [otlp]

      processors: []

      exporters:

        - loadbalancing/logs

Компоненты

Для нашей конфигурации мы используем следующие компоненты.

Приемники

В разделе receivers мы настраиваем приемник otlp для получения данных по gRPC и HTTP.

Экспортеры

В разделе exporters мы настраиваем три loadbalancing exporters, по одному для каждого сигнала. Все экспортёры настроены на использование резолвера k8s, который использует сервис Kubernetes для определения пула Collector для отправки данных. Одна из причин разделения дальнейшей обработки по сигналам заключается в том, что каждый сигнал, вероятно, получает разный объём трафика: например, вы можете получать большой объём логов, несколько трассировок и относительно мало метрик. Поэтому желательно, чтобы пул Collector, обрабатывающий логи, был больше пула, обрабатывающего метрики; выделение дополнительных Collector для обработки меньшего количества метрик может привести к непроизводительному расходу ресурсов.

Сервисные контейнеры

В наших контейнерах мы получаем данные по протоколу OTLP и экспортируем их через Load Balancing Exporter для конкретного сигнала, не выполняя никакой дополнительной обработки. Поскольку этот Collector предназначен исключительно для балансировки нагрузки, мы хотим выполнять как можно меньше обработки, чтобы он мог обработать как можно больше данных.