RKDEEP

Мониторинг потоковых приложений Kafka Stream c Grafana + Prometheus

Kirill Rybkin2021-10-01

Для понимания, как работает ваше приложение, необходимо отслеживать определенный набор показателей. Доступ к показателям Kafka и java приложений в целом можно получить через интерфейс расширений JMX. Использовать во внешней системе метрики удобно через java agent напр. jmx_exporter для prometheus.

Какие метрики выбрать для мониторинга?

У приложений Kafka множество показателей для отслеживания функционирования. Их столько, что можно легко запутаться, что важно отслеживать, а что можно не учитывать. Важно выбрать определенный пул показателей и не следить за слишком большим их количеством. При настройке уведомлений высока вероятность усталости от постоянных алармов определенных метрик и пропуска важных сигналов. Например отставания потребителя - метрика которая может генерировать большое количество алармов из-за краковременных всплесков нагрузки, в таком случае возможно стоит рассмотреть end to end latency как более общую метрику. Думаю ход мыслей тут понятен.

Основные метрики:

  • Отставание потребителя (consumer lag)
  • Суммарная по всем темам входящая скорость передачи данных [байт/с];
  • Суммарная по всем темам исходящая скорость передачи данных [байт/с];
  • Суммарная частота входящих сообщений по всем темам.
  • Использование CPU;
  • Пропускная способность сети на вход;
  • Пропускная способность сети на выход;
  • Среднее время ожидания диска;
  • Процент использования диска. и т.д.
    Метрик для контроля много и с полным списком можно ознакомится в документации.

Инструменты для мониторинга

Для мониторинга будем использовать Prometheus + Grafana + различные exporter данных для Prometheus, архитектура представлена на диаграмме снизу:

monitoring architecture
Описывать настройку будем в базовом варианте и не коснемся части компонентов напр. alert, short-live jobs и т.д.

Быстрый взгляд на используемые компоненты:

  1. Prometheus является открытой (Apache 2.0) time series СУБД, написанной на языке Go и изначально разработанной в компании SoundCloud. Другими словами, эта штука хранит ваши метрики. Интересной особенностью Prometheus является то, что он сам тянет метрики с заданного множества сервисов (делает pull). За счет этого у Prometheus не могут забиться какие-то там очереди или вроде того, а значит мониторинг никогда не станет узким местом системы. Также проект интересен тем, что он принципиально не предлагает какого-либо горизонтального масштабирования или high availability.

  2. Grafana представляет собой открытый (Apache 2.0) веб-фронтенд к различным time series СУБД, таким, как Graphite, InfluxDB, Prometheus. В общем, Grafana рисует для вас красивые графики, используя информацию из Prometheus.

  3. Kafka-lag-exporter приложение написанное на scala, которое опрашивает Kafka брокер и преобразует в метрики для Prometheus. Как видно из названия приложение предоставляет Lag метрику. В количественном и временном (интерполированном) значение. Lag важен для понимания задержки потоковых приложений.

  4. JMX exporter- этот exporter предназначен для запуска как Java агент, запуская Http сервер и предоставляя метрики локальной JVM в формате Prometheus.

Настраиваем мониторинг:

Наблюдать будем за метриками:

  • Kafka брокера;
  • Kafka-stream приложения;
  • Lag обработки сообщений в топике, в абсолютных единицах и временных.

Устанавливаем Prometheus

sudo useradd --no-create-home --shell /bin/false prometheus
# Свежий пакет находим здесь:
# https://github.com/prometheus/prometheus/releases
wget https://github.com/prometheus/prometheus/releases/download/v2.30.2/prometheus-2.30.2.linux-amd64.tar.gz
tar -xvzf prometheus-2.30.2.linux-amd64.tar.gz
sudo cp prometheus-2.30.2.linux-amd64/prometheus /usr/local/bin/
sudo cp prometheus-2.30.2.linux-amd64/promtool /usr/local/bin/

sudo mkdir /etc/prometheus
sudo cp -r prometheus-2.30.2.linux-amd64/consoles/ /etc/prometheus/consoles
sudo cp -r prometheus-2.30.2.linux-amd64/console_libraries/ /etc/prometheus/console_libraries
sudo cp prometheus-2.30.2.linux-amd64/prometheus.yml /etc/prometheus/
sudo chown -R prometheus:prometheus /etc/prometheus

sudo mkdir /var/lib/prometheus
sudo chown prometheus:prometheus /var/lib/prometheus

Создаем /etc/systemd/system/prometheus.service:

[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target

[Service]
User=prometheus
Group=prometheus
ExecStart=/usr/local/bin/prometheus \
    --config.file /etc/prometheus/prometheus.yml \
    --storage.tsdb.path /var/lib/prometheus/ \
    --web.console.templates=/etc/prometheus/consoles \
    --web.console.libraries=/etc/prometheus/console_libraries

[Install]
WantedBy=default.target

Запускаем Prometheus

sudo systemctl daemon-reload
sudo systemctl start prometheus
sudo systemctl status prometheus
sudo systemctl enable prometheus

Проверяем, что Prometheus отдает свои собственные метрики:

curl 'localhost:9090/metrics'

Добавляем job в конфигурацию prometheus (/etc/prometheus/prometheus.yml), для периодического опроса метрик приложений.

scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'prometheus'

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

   # Override the global default and scrape targets from this job every 5 seconds.
    scrape_interval: 5s

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
    - targets: ['localhost:9090']
      labels:
        instance: 'prometheus:9090'

  - job_name: "kafka-broker"
    static_configs:
      - targets:
          - "localhost:1234"
        labels:
          env: "dev"
    relabel_configs:
      - source_labels: [__address__]
        target_label: instance
        regex: '([^:]+)(:[0-9]+)?'
        replacement: '${1}'

  - job_name: "kafka-lag-exporter"
    static_configs:
      - targets:
          - "localhost:9999"
        labels:
          env: "dev"
    relabel_configs:
      - source_labels: [__address__]
        target_label: instance
        regex: '([^:]+)(:[0-9]+)?'
        replacement: '${1}' 

  - job_name: "kafka-stream"
    static_configs:
      - targets:
          - "localhost:1235"

Проверяем созданные job в простеньком веб-интерфейсе с доступными endpoint http://localhost:9090/targets

Собираем экпортеры

Для jmx метрик (напр. брокер kafka и kafka stream приложений) необходим jmx-exporter. Для мониторинга лагов обработки сообщений можно использовать приложение kafka-lag-exporter от Lightbend. JMX_exporter доступен на github, собираем:

git clone https://github.com/prometheus/jmx_exporter.git
cd jmx_exporter
mvn package

Узнаем имя jar файла

ls jmx_prometheus_javaagent/target/jmx*jar

Jmx Exporter - это jar файл который должен быть загружен в Java environment для функционирования, он запускается как параметр JMV -javaagent.
Сохраняем конфигурации для javaagent:

wget https://raw.githubusercontent.com/confluentinc/jmx-monitoring-stacks/6.1.0-post/shared-assets/jmx-exporter/kafka_streams.yml
cp kafka_streams.yml /etc/prometheus/

wget https://raw.githubusercontent.com/confluentinc/jmx-monitoring-stacks/6.1.0-post/shared-assets/jmx-exporter/kafka_broker.yml
cp kafka_broker.yml /etc/prometheus/

Для мониторинга брокера kafka добавляем перед запуском:

export EXTRA_ARGS="-Dcom.sun.management.jmxremote \
    -Dcom.sun.management.jmxremote.authenticate=false \
    -Dcom.sun.management.jmxremote.ssl=false \
    -Djava.util.logging.config.file=logging.properties \
    -javaagent:./jmx_exporter/jmx_prometheus_javaagent/target/jmx_prometheus_javaagent-0.16.1-SNAPSHOT.jar=1234:/etc/prometheus/kafka_broker.yml

Для kafka stream перед стартом приложения:

-javaagent:./jmx_exporter/jmx_prometheus_javaagent/target/jmx_prometheus_javaagent-0.16.1-SNAPSHOT.jar=1235:/etc/prometheus/kafka_stream.yml

Для получения задержки обработки сообщений необходимо запустить приложение kafka-lag-exporter:

wget https://github.com/lightbend/kafka-lag-exporter/releases/download/v0.6.7/kafka-lag-exporter-0.6.7.zip
unzip kafka-lag-exporter-0.6.7.zip
mkdir /opt/kafka-lag-exporter
cp ./kafka-lag-exporter-0.6.7 /opt/kafka-lag-exporter

/opt/kafka-lag-exporter/bin/kafka-lag-exporter \
    -Dconfig.file=/etc/conf/application.conf 

Минимально необходимо переопределить bootstrap-brokers в конфигурации.

kafka-lag-exporter {
  reporters {
    prometheus {
      port = 9999
    }
  }
  lookup-table-size = 120
  clusters = [
    {
      name = "a-cluster"
      bootstrap-brokers = "localhost:9092"
    }
  ]
}

Запускаем Grafana

# Ссылку на свежий пакет находим тут:
# https://grafana.com/grafana/download

wget https://dl.grafana.com/oss/release/grafana_5.4.2_amd64.deb
sudo apt install ./grafana_5.4.2_amd64.deb
sudo systemctl start grafana-server
sudo systemctl status grafana-server
sudo systemctl enable grafana-server

Добавляем дашборды в Grafana:

Идем на порт 3000 с логином и паролем admin. Grafana сразу предложит сменить пароль. Дальше проходим незамысловатые диалоги, и добавляем Prometheus в качестве источника данных. Заходим в управление дашбордами и добавляем импорты из json. Листинги дашбордов в grafana:

Материалы

  1. "Apache Kafka. Потоковая обработка и анализ данных" Нархид Ния, Шапира Гвен, Палино Тодд.
  2. "Kafka Streams в действии. Приложения и микросервисы для работы в реальном времени" Беджек Билл.
  3. How to Monitor Kafka