かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Spring Boot + Spring Integration でいろいろ試してみる ( その41 )( Docker Compose でサーバを構築する、Kafka 編8 - broker の metrics を収集・表示する )

概要

記事一覧はこちらです。

Kafka の broker の metrics を Prometheus、Grafana を使って収集・表示させてみます。

参照したサイト・書籍

  1. Kafka Monitoring with Prometheus, Telegraf, and Grafana
    https://medium.com/activewizards-machine-learning-company/kafka-monitoring-with-prometheus-telegraf-and-grafana-6228fed736f1

  2. prometheus/jmx_exporter
    https://github.com/prometheus/jmx_exporter

  3. sscaling/jmx-prometheus-exporter
    https://hub.docker.com/r/sscaling/jmx-prometheus-exporter

  4. 1.12 DC/OS Global Kafka Dashboard
    https://grafana.com/grafana/dashboards/9018

  5. Prometheusクエリ道場
    https://qiita.com/t_nakayama0714/items/1231751e72804d52c20a

  6. クエリの基礎 - Prometheusドキュメント
    http://it-engineer.hateblo.jp/entry/2019/01/19/150849

目次

  1. 方針
  2. docker-compose.yml に jmx_exporter、prometheus、grafana コンテナを追加する
  3. application.properties から cp-kafka4、cp-kafka5 の設定を削除する
  4. docker-compose up -d コマンドでコンテナを起動する
  5. Topic1 の名前の topic を作成する
  6. アプリケーションを起動してメッセージを送受信する
  7. Grafana に 1.12 DC/OS Global Kafka Dashboard を追加する
  8. broker の metrics が表示されるよう Dashboard の Metrics、Legend の設定を変更する

手順

方針

  • 現在5つの Kafka の broker(cp-kafka1~5)を起動していますが、cp-kafka4, cp-kafka5 を停止して3つに減らします。
  • broker の metrics の収集には prometheus/jmx_exporter を使用します。
  • prometheus/jmx_exportersscaling/jmx-prometheus-exporter を使用して Kafka とは別のコンテナで起動します。
  • Prometheus、Grafana もコンテナで起動します。バージョンは最新バージョンを使用します。
  • Prometheus の /prometheus はローカルディレクトリには関連付けません。収集したデータはコンテナ内に保持します(コンテナを停止すると失われます)。
  • Grafana の /var/lib/grafana はローカルディレクトリに関連付けて、コンテナを停止しても設定内容が維持されるようにします。
  • Grafana の Dashboard には 1.12 DC/OS Global Kafka Dashboard を利用します。そのままでは何も表示されないので、収集先の Metrics は変更します。

docker-compose.yml に jmx_exporter、prometheus、grafana コンテナを追加する

docker/jmx-prometheus-exporter ディレクトリを新規作成した後、その下に prometheus/jmx_exporter 用の設定ファイル cp-kafka1-config.yml、cp-kafka2-config.yml、cp-kafka3-config.yml を新規作成して以下の内容を記載します。jmxUrl 以外は jmx_exporter/example_configs/kafka-2_0_0.yml に記載されている内容をそのままコピーします。

■cp-kafka1-config.yml

jmxUrl: service:jmx:rmi:///jndi/rmi://cp-kafka1:9991/jmxrmi
※ここから下には https://github.com/prometheus/jmx_exporter/blob/master/example_configs/kafka-2_0_0.yml の記載内容をコピーすること。

■cp-kafka2-config.yml

jmxUrl: service:jmx:rmi:///jndi/rmi://cp-kafka2:9991/jmxrmi
※ここから下には https://github.com/prometheus/jmx_exporter/blob/master/example_configs/kafka-2_0_0.yml の記載内容をコピーすること。

■cp-kafka3-config.yml

jmxUrl: service:jmx:rmi:///jndi/rmi://cp-kafka3:9991/jmxrmi
※ここから下には https://github.com/prometheus/jmx_exporter/blob/master/example_configs/kafka-2_0_0.yml の記載内容をコピーすること。

docker/prometheus ディレクトリを新規作成した後、その下に prometheus.yml を新規作成して以下の内容を記載します。各 job に instance の label を定義していますが、これは Grafana に表示させる時の instance 名を target 名(jmx-prometheus-exporter1:5556 等)ではなくコンテナ名にするためです。

global:
  scrape_interval: 15s
  evaluation_interval: 15s
scrape_configs:
  - job_name: 'cp-kafka1-jmx'
    static_configs:
      - targets:
          - jmx-prometheus-exporter1:5556
        labels:
          instance: 'cp-kafka1'
  - job_name: 'cp-kafka2-jmx'
    static_configs:
      - targets:
          - jmx-prometheus-exporter2:5556
        labels:
          instance: 'cp-kafka2'
  - job_name: 'cp-kafka3-jmx'
    static_configs:
      - targets:
          - jmx-prometheus-exporter3:5556
        labels:
          instance: 'cp-kafka3'

docker/grafana/storage ディレクトリを新規作成します。

docker-compose.yml を以下のように変更します。

  cp-kafka1:
    image: confluentinc/cp-kafka:5.3.0
    container_name: cp-kafka1
    ports:
      - "19092:19092"
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: cp-zookeeper1:12181,cp-zookeeper2:22181,cp-zookeeper3:32181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://cp-kafka1:19092
      KAFKA_JMX_PORT: 9991
    depends_on:
      - cp-zookeeper1
      - cp-zookeeper2
      - cp-zookeeper3
  cp-kafka2:
    image: confluentinc/cp-kafka:5.3.0
    container_name: cp-kafka2
    ports:
      - "29092:29092"
    environment:
      KAFKA_BROKER_ID: 2
      KAFKA_ZOOKEEPER_CONNECT: cp-zookeeper1:12181,cp-zookeeper2:22181,cp-zookeeper3:32181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://cp-kafka2:29092
      KAFKA_JMX_PORT: 9991
    depends_on:
      - cp-zookeeper1
      - cp-zookeeper2
      - cp-zookeeper3
  cp-kafka3:
    image: confluentinc/cp-kafka:5.3.0
    container_name: cp-kafka3
    ports:
      - "39092:39092"
    environment:
      KAFKA_BROKER_ID: 3
      KAFKA_ZOOKEEPER_CONNECT: cp-zookeeper1:12181,cp-zookeeper2:22181,cp-zookeeper3:32181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://cp-kafka3:39092
      KAFKA_JMX_PORT: 9991
    depends_on:
      - cp-zookeeper1
      - cp-zookeeper2
      - cp-zookeeper3
  ..........

  # Docker JMX exporter for Prometheus
  # https://hub.docker.com/r/sscaling/jmx-prometheus-exporter
  # https://github.com/prometheus/jmx_exporter
  jmx-prometheus-exporter1:
    image: sscaling/jmx-prometheus-exporter:0.12.0
    container_name: jmx-prometheus-exporter1
    # Docker Network 内で通信できればよいので ports は設定しないが、動作確認したい時はコメントアウトを
    # 解除する
    # ports:
    #   - "5556:5556"
    volumes:
      - ./docker/jmx-prometheus-exporter/cp-kafka1-config.yml:/opt/jmx_exporter/config.yml
    depends_on:
      - cp-kafka1
  jmx-prometheus-exporter2:
    image: sscaling/jmx-prometheus-exporter:0.12.0
    container_name: jmx-prometheus-exporter2
    volumes:
      - ./docker/jmx-prometheus-exporter/cp-kafka2-config.yml:/opt/jmx_exporter/config.yml
    depends_on:
      - cp-kafka2
  jmx-prometheus-exporter3:
    image: sscaling/jmx-prometheus-exporter:0.12.0
    container_name: jmx-prometheus-exporter3
    volumes:
      - ./docker/jmx-prometheus-exporter/cp-kafka3-config.yml:/opt/jmx_exporter/config.yml
    depends_on:
      - cp-kafka3

  prometheus:
    image: prom/prometheus:v2.12.0
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml

  grafana:
    image: grafana/grafana:6.3.5
    container_name: grafana
    ports:
      - "3000:3000"
    environment:
      - TZ=Asia/Tokyo
    volumes:
      - ./docker/grafana/storage:/var/lib/grafana
  • 上のソース内には記載していませんが、以下の点を変更します。
    • cp-kafka4、cp-kafka5 のコンテナの設定をコメントアウトします。
    • cp-schema-registry1~3 の environment の SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS から ,cp-kafka4:49092,cp-kafka5:59092 を削除します。
  • cp-kafka1~cp-kafka3 の environment に KAFKA_JMX_PORT: 9991 を追加します。
  • 以下のコンテナの設定を追加します。
    • jmx-prometheus-exporter1(cp-kafka1 の metrics 収集用)
    • jmx-prometheus-exporter2(cp-kafka2 の metrics 収集用)
    • jmx-prometheus-exporter3(cp-kafka3 の metrics 収集用)
    • prometheus
    • grafana

application.properties から cp-kafka4、cp-kafka5 の設定を削除する

src/main/resources/application.properties の以下の点を変更します。

spring.kafka.bootstrap-servers=cp-kafka1:19092,cp-kafka2:29092,cp-kafka3:39092
..........
  • spring.kafka.bootstrap-servers=cp-kafka1:19092,cp-kafka2:29092,cp-kafka3:39092,cp-kafka4:49092,cp-kafka5:59092spring.kafka.bootstrap-servers=cp-kafka1:19092,cp-kafka2:29092,cp-kafka3:39092 に変更します。

docker-compose up -d コマンドでコンテナを起動する

docker-compose up -d コマンドでコンテナを起動します。

f:id:ksby:20190908224135p:plain f:id:ksby:20190908224302p:plain

http://localhost:1936/haproxy-cp-schema-registry?stats にアクセスして cp-schema-registry のステータスが全て緑になるまで待機します(cp-schema-registry が使用可能になれば他も全て使用可能な状態になっています)。

f:id:ksby:20190908224444p:plain

http://localhost:9090/ にアクセスして Prometheus の画面が表示されることを確認した後、画面上部の query 入力部に kafka と入力し Kafka の metrics が表示されることを確認します。

f:id:ksby:20190908224817p:plain

http://localhost:3000/ にアクセスして Grafana のログイン画面が表示されることを確認します。

f:id:ksby:20190908225215p:plain

Topic1 の名前の topic を作成する

cp-kafka1 コンテナに接続して kafka-topics --zookeeper cp-zookeeper1:12181 --create --topic Topic1 --partitions 3 --replication-factor 3 --if-not-exists コマンドを実行して Topic1 の名前の topic を作成します。

f:id:ksby:20190908225738p:plain

アプリケーションを起動してメッセージを送受信する

アプリケーションを起動してメッセージの送受信が行われるようにします。

f:id:ksby:20190908230117p:plain

Grafana に 1.12 DC/OS Global Kafka Dashboard を追加する

Prometheus で query に kafka_server_brokertopicmetrics_messagesin_total を入力・実行して、cp-kafka1~3 から metrics を収集できていることを確認します。

f:id:ksby:20190908230902p:plain

http://localhost:3000/ にアクセスして Grafana のログイン画面を表示してから admin / admin でログインします。

「Home Dashboard」の画面が表示されたら「add data source」をクリックして Prometheus を data source として追加します。

f:id:ksby:20190908231123p:plain f:id:ksby:20190908231315p:plain f:id:ksby:20190908231523p:plain

次に 1.12 DC/OS Global Kafka Dashboarddashboard を追加します。画面左側の「+」-「Create」-「Import」メニューをクリックします。

f:id:ksby:20190908232047p:plain

「Import」画面が表示されるので 1.12 DC/OS Global Kafka Dashboard の ID である 9018 を入力して「Load」ボタンをクリックします。

f:id:ksby:20190908232349p:plain f:id:ksby:20190908232513p:plain

「prometheus」の項目で前に登録した Prometheus の data source を選択した後、「Import」ボタンをクリックします。

f:id:ksby:20190908232700p:plain

1.12 DC/OS Global Kafka Dashboard の画面が表示されますが、取得する metrics の設定が合っていないので現時点では何も表示されません。

f:id:ksby:20190908232924p:plain

broker の metrics が表示されるよう Dashboard の Metrics、Legend の設定を変更する

基本的には以下のルールで変更します(このルールに該当しないものもあります)。

  • Metrics に kafka_...persec_Xminuterate(X は 1, 5, 15 のいずれかが書かれている)と記載されている場合には、この部分を kafka_...persec_XXXratedelta(kafka_..._total[Xm]) に変更します。
  • topic 属性が付く metrics の場合、 f:id:ksby:20190909000933p:plain 総数の metrics だけが必要な場合には {topic=""} を、topic 別の metrics が必要な場合には {topic=~".+"} を付加します(そうしないと総数と個別の両方の値が加算されて数値が2倍になってしまうため)。
  • Metrics に by(service_name) と記載されている場合、by(instance) に変更します。
  • Metrics の最後に _max_mean があるものは取り除きます。
  • Legend は、以下のいずれかのパターンで変更します。
    • {{service_name}} // {{task_name}}{{instance}}
    • {{service_name}}{{instance}}
    • {{service_name}} / {{task_name}}{{instance}} / {{topic}}(metrics に topic 属性がある場合)
  • Title は変更しません。

Metrics は以下の手順で変更します。Panel の「Edit」メニューを選択してから、

f:id:ksby:20190908235154p:plain

「Metrics」を(必要があれば「Legend」も)変更します。設定が正しければ上のグラフが表示されるようになります。

f:id:ksby:20190908235648p:plain f:id:ksby:20190908235814p:plain

左上の矢印ボタンをクリックして戻ると Panel にグラフが表示されます。

f:id:ksby:20190908235901p:plain

実際には以下の設定に変更しました。1行だけ書いてあるものは Metrics のみ、2行書いてあるものは Metrics と Legend を変更しています。

  • Global Kafka Overview
    • Global avg msg/sec (1m)
      • sum(delta(kafka_server_brokertopicmetrics_messagesin_total{topic=""}[1m]))
    • Global avg msg/sec (5m)
      • sum(delta(kafka_server_brokertopicmetrics_messagesin_total{topic=""}[5m]))
    • Global avg msg/sec (15m)
      • sum(delta(kafka_server_brokertopicmetrics_messagesin_total{topic=""}[15m]))
    • Disk Used per Agent
      • 何も変更しません(今回はデータを表示しません)。
    • Kafka avg msg/sec (1m) by Topic
      • sum(delta(kafka_server_brokertopicmetrics_messagesin_total{topic=~".+"}[1m]))by(topic)
    • Kafka avg msg/sec (5m) by Topic
      • sum(delta(kafka_server_brokertopicmetrics_messagesin_total{topic=~".+"}[5m]))by(topic)
    • Kafka avg msg/sec (15m) by Topic
      • sum(delta(kafka_server_brokertopicmetrics_messagesin_total{topic=~".+"}[15m]))by(topic)
    • Heap Memory in Use
      • 何も変更しません(今回はデータを表示しません)。
    • Number of Leaders per (Service / Broker)
      • Metrics は変更しません。
      • {{instance}}
    • Partition Count Across Brokers (Service / Broker)
      • Metrics は変更しません。
      • {{instance}}
  • Broker Info
    • ActiveControllerCount
      • max(kafka_controller_kafkacontroller_activecontrollercount)by(instance)
      • {{instance}}
    • Under Replicated Partitions
      • max(kafka_cluster_partition_underreplicated)by(instance)
      • {{instance}}
    • Offline Partitions
      • max(kafka_controller_kafkacontroller_offlinepartitionscount)by(instance)
      • {{instance}}
    • Total Partition Count (Service / Broker)
      • Metrics は変更しません。
      • {{instance}}
    • ISR Expansion Rate (Service / Broker)
      • delta(kafka_server_replicamanager_isrexpands_total[5m])
      • {{instance}}
    • ISR Shrink Rate (Service / Broker)
      • delta(kafka_server_replicamanager_isrshrinks_total[5m])
      • {{instance}}
    • Producer Purgatory Requests Waiting
      • sum(kafka_server_delayedoperationpurgatory_numdelayedoperations)by(instance)
      • {{instance}}
    • Delayed Fetch Operation Purgatory Size
      • sum(kafka_server_delayedoperationpurgatory_purgatorysize)by(instance)
      • {{instance}}
    • Kafka avg msg/sec (1m) per (Service / Broker)
      • delta(kafka_server_brokertopicmetrics_messagesin_total{topic=~".+"}[1m])
      • {{instance}} / {{topic}}
    • Kafka avg msg/sec (5m) per (Service / Broker)
      • delta(kafka_server_brokertopicmetrics_messagesin_total{topic=~".+"}[5m])
      • {{instance}} / {{topic}}
    • Kafka avg msg/sec (15m) per (Service / Broker)
      • delta(kafka_server_brokertopicmetrics_messagesin_total{topic=~".+"}[15m])
      • {{instance}} / {{topic}}
    • All Bytes In (1min) per (Service / Broker)
      • delta(kafka_server_brokertopicmetrics_bytesin_total{topic=~".+"}[1m])
      • {{instance}} / {{topic}}
    • All Bytes Out (1min) per (Service / Broker)
      • delta(kafka_server_brokertopicmetrics_bytesout_total{topic=~".+"}[1m])
      • {{instance}} / {{topic}}
    • All Bytes In (15min) per (Service / Broker)
      • delta(kafka_server_brokertopicmetrics_bytesin_total{topic=~".+"}[15m])
      • {{instance}} / {{topic}}
    • All Bytes Out (15min) per (Service / Broker)
      • delta(kafka_server_brokertopicmetrics_bytesout_total{topic=~".+"}[15m])
      • {{instance}} / {{topic}}
  • Leaders
    • Max Recorded Leader Election Latency (ms)
      • max(kafka_controller_controllerstats_leaderelectionrateandtimems)by(instance)
      • {{instance}}
    • Unclean Leader Elections (15min)
      • max(delta(kafka_controller_controllerstats_uncleanleaderelections_total[15m]))by(instance)
      • {{instance}}
    • Avg Time Request Waits for Follower (ms)
      • avg(kafka_network_requestmetrics_remotetimems)by(instance)
      • {{instance}}
    • Max Lag - Follower/Leader Replicas
      • max(kafka_server_replicafetchermanager_maxlag)by(instance)
      • {{instance}}
  • Requests
    • Current Request Queue Size (Service / Broker)
      • Metrics は変更しません。
      • {{instance}}
    • Avg Total Time Request Serve (ms)
      • avg(kafka_network_requestmetrics_totaltimems)by(instance)
      • {{instance}}
    • Avg Request Response Time (ms)
      • avg(kafka_network_requestmetrics_responsesendtimems)by(instance)
      • {{instance}}
    • Avg Request Waiting Time in Request Queue (ms)
      • avg(kafka_network_requestmetrics_requestqueuetimems)by(instance)
      • {{instance}}
    • Avg Request Waiting Time in Response Queue (ms)
      • avg(kafka_network_requestmetrics_responsequeuetimems)by(instance)
      • {{instance}}
    • Avg Request Processing Time (ms) at Leader
      • avg(kafka_network_requestmetrics_localtimems)by(instance)
      • {{instance}}
    • Produce Request Rate / sec (15min) by (Service / Broker)
      • delta(kafka_server_brokertopicmetrics_totalproducerequests_total{topic=~".+"}[15m])
      • {{instance}} / {{topic}}
    • Fetch Request Rate / sec (15min) by (Service / Broker)
      • delta(kafka_server_brokertopicmetrics_totalfetchrequests_total{topic=~".+"}[15m])
      • {{instance}} / {{topic}}
  • Network Info
    • Network Request Rate / sec (15min) by (Service / Broker)
      • delta(kafka_server_fetcherstats_requests_total[15m])
      • {{instance}} / {{broker_port}}
    • Network Processor Idle (%)
      • sum(kafka_network_processor_idlepercent)by(instance)
      • {{instance}}

変更すると以下のようにデータが表示されます(Panel が多いのでキャプチャは1ページのみ)。

f:id:ksby:20190909013453p:plain

履歴

2019/09/09
初版発行。