DEV Community

Álvaro Bacelar for Kafka BR

Posted on • Updated on

Monitorando Consumer Lag do Apache Kafka

O Apache Kafka tem milhares de métricas que podem ser acessadas via interface JMX (nesse artigo eu mostro como instrumentar tais métricas utilizando ferramentas Open Source). Contudo há uma métrica, não menos importante, que não está disponível via JMX: O Consumer Lag.

Mensurada em número de mensagem, basicamente o Lag é a diferença entre a última mensagem produzida em uma partição especifica e a última mensagem processada (committed) pelo consumidor.

Segundo o livro "kafka - The Definitive Guide" o método preferido para monitorar o Lag é através de uma aplicação externa que possa visualizar o estado de uma partição no broker, rastreando o offset mais recente da mensagem produzida e o último offset processado pelo consumidor, atraves do topico interno de controle: __consumer_offsets

Levando isso em consideração, o LinkedIn (empresa responsável pela criação do Apache Kafka) desenvolveu (também) uma aplicação que realiza essa rastreabilidade dos offsets das partições dos brokers. Essa aplicação é o Burrow.

O Burrow é uma ferramenta que foi escrita na linguagem Go e ela nos provê tanto informações de Consumer Lag quanto informações diversas do cluster e disponibiliza tais valores via REST API. Com o Burrow ainda é possível enviar notificações via email ou WebHook com um threshold definido.

Como falei acima, o Burrow provê essas informações via REST API e nosso objetivo aqui é fazer essa informação chegar no Prometheus e consequentemente no Grafana.

Então irei mostrar como instalar e configurar o Burrow juntamente com o burrow_exporter (também escrito em Go) para monitorar o Consumer Lag de um cluster Apache Kafka e ter todas as informações do Lag, entre outras, no Prometheus.

Para realizar todos os testes desse artigo, eu realizei o setup de um cluster Apache Kafka com o Ansible. Clicando aqui você verá um artigo que escrevi mostrando como realizar um setup de um cluster Apache Kafka e Zookeeper com o Ansible.

Instalando e Configurando o Prometheus

Para instalar e configurar o Prometheus vamos seguir os seguintes passos:

# wget https://github.com/prometheus/prometheus/releases/download/v2.12.0/prometheus-2.12.0.linux-amd64.tar.gz
Enter fullscreen mode Exit fullscreen mode
  • Descompactando no diretório /srv
# tar -zxvf prometheus-2.12.0.linux-amd64.tar.gz -C /srv/
Enter fullscreen mode Exit fullscreen mode
  • Adicionar usuário de serviço do prometheus
# useradd -s /usr/sbin/nologin prometheus
Enter fullscreen mode Exit fullscreen mode
  • Mudar o dono da pasta do prometheus
# chown prometheus:prometheus /srv/prometheus-2.12.0.linux-amd64/ -R
Enter fullscreen mode Exit fullscreen mode
  • Adicionar o arquivo de service do prometheus
# vim /etc/systemd/system/prometheus.service
Enter fullscreen mode Exit fullscreen mode
[Unit]
Description=Prometheus
After=network-online.target
[Service]
Type=simple
User=prometheus
Group=prometheus
ExecReload=/bin/kill -HUP $MAINPID
ExecStart=/srv/prometheus-2.12.0.linux-amd64/prometheus --config.file=/srv/prometheus-2.12.0.linux-amd64/prometheus.yml --storage.tsdb.path=/srv/prometheus-2.12.0.linux-amd64/data --web.listen-address=0.0.0.0:9090
LimitNOFILE=65000
LockPersonality=true
NoNewPrivileges=true
MemoryDenyWriteExecute=true
PrivateDevices=true
PrivateTmp=true
ProtectHome=true
RemoveIPC=true
RestrictSUIDSGID=true
ProtectSystem=full
SyslogIdentifier=prometheus
Restart=always
[Install]
WantedBy=multi-user.targe
Enter fullscreen mode Exit fullscreen mode
  • Executar o daemon-reload e iniciar o serviço
# systemctl daemon-reload
# systemctl start prometheus
Enter fullscreen mode Exit fullscreen mode

Se tudo tiver dado certo o serviço subiu na porta 9090 e podemos acessar nessa porta:
http://127.0.0.1:9090

Instalando o Grafana

A instalação do Grafana é mais fácil, para instala-lo basta acessar o seguinte link https://grafana.com/grafana/download e seguir os passos descrito no link de acordo com seu S.O.

Depois de instalado suba o serviço

# systemctl start grafana-server
Enter fullscreen mode Exit fullscreen mode

O Grafana por padrão sobe na porta 3000, então vamos acessa-lo:
http://127.0.0.1:3000

O usuário e senha default do Grafana é admin, no seu primeiro acesso é solicitado para trocar.

Após acessar o Grafana, você deve adicionar o datasource do Prometheus.

Instalando e configurando o Burrow

O primeiro passo para instalar o Burrow é realizar o download do código fonte, para isso vá ao repositório oficial do Burrow no link abaixo:

$ git clone https://github.com/linkedin/Burrow.git
Enter fullscreen mode Exit fullscreen mode

Com o código fonte do Burrow, vamos entrar no diretório e buildar a imagem Docker:

$ cd ${PWD}/Burrow
$ docker build -t burrow-api .
Enter fullscreen mode Exit fullscreen mode

Nesse post irei focar na instalação do Burrow via Docker. Para aqueles que preferirem executar o Burrow sem o uso do Docker, é só seguir os passos que estão descritos no README.rd do repositório do Burrow.

Com a imagem do Burrow buildada vamos agora realizar o mesmo procedimento com a imagem do burrow_exporter. Baixe o código fonte no link abaixo:

GitHub logo alvarobacelar / burrow_exporter

A Prometheus Exporter for gathering Kafka consumer group info from Burrow

git clone https://github.com/alvarobacelar/burrow_exporter.git
Enter fullscreen mode Exit fullscreen mode

O repositório acima é um fork do projeto burrow_exporter criado por Shamil. Eu solicitei um Pull Request há um tempo para adicionar alguns recursos extras. Mas o dono do repositório nunca respondeu, então vamos seguir usando o projeto que forkei, pois ele retorna um valor a mais que a API do Burrow nos disponibiliza (iremos ver isso logo mais na frente).

Entrando na pasta do do burrow_exporter, que acabamos de baixar, vamos buildar a imagem Docker:

$ docker build -t burrow-exporter . 
Enter fullscreen mode Exit fullscreen mode

Agora que temos as imagens do Burrow e burrow_exporter criadas, vamos
criar o arquivo docker-compose.yml para subirmos as duas aplicações posteriormente. O arquivo deve conter o seguinte conteúdo:

version: "2"
services:
  burrow:
    image: burrow-api
    volumes:
      - ${PWD}/config:/etc/burrow/
    container_name: burrow_api

  burrow_exporter:
    image: burrow-exporter
    container_name: burrow_exporter
    ports:
      - 8090:8237
    depends_on:
      - burrow
    command: --burrow.address http://burrow:8000
Enter fullscreen mode Exit fullscreen mode

Antes de subir os containers precisamos adicionar os servidores do kafka e zookeeper no arquivo de configuração do Burrow. Dentro do diretório da API do Burrow vamos editar o arquivo burrow.toml

$ vim ${PWD}/Burrow/config/burrow.toml
Enter fullscreen mode Exit fullscreen mode

No arquivo vamos alterar os endereços dos brokers, Zookeeper e outros parâmetros:

[general]
pidfile="burrow.pid"
stdout-logfile="burrow.out"
access-control-allow-origin="mysite.example.com"

[logging]
filename="logs/burrow.log"
level="info"
maxsize=100
maxbackups=30
maxage=10
use-localtime=false
use-compression=true

[zookeeper]
servers=[ "zkhost01.example.com:2181", "zkhost02.example.com:2181", "zkhost03.example.com:2181" ] # altere para os edereços de seus zookeepers
timeout=6
root-path="/burrow"

############################
####### CLUSTER zoom #######
############################
# altere o nome do profile do cliente caso queira
[client-profile.post]
client-id="burrow-monitor"
kafka-version="2.3.0" # altere para a versão 2.3.0 do Kafka

# Dê um nome para o seu cluster [cluster.nome]
[cluster.zoom]
class-name="kafka"
servers=[ "kafka01.example.com:10251", "kafka02.example.com:10251", "kafka03.example.com:10251" ] # altere para os endereços dos seus brokers
client-profile="post" # coloque aqui o nome do client-profile definido acima 
topic-refresh=120
offset-refresh=30

# Dê um nome para o seu cluster [cluster.nome]
[consumer.zoom]
class-name="kafka"
cluster="zoom" # coloque aqui o nome do cluster definido
servers=[ "kafka01.example.com:10251", "kafka02.example.com:10251", "kafka03.example.com:10251" ] # altere para os endereços dos seus brokers
client-profile="post" # coloque aqui o nome do client-profile definido 
group-blacklist="^(console-consumer-|python-kafka-consumer-|quick-).*$" # coloque aqui os nomes dos consumer groups que não quer que apareça
group-whitelist=""
################################
####### FIM CLUSTER zoom #######
################################
# Repita isso para quantos clusters tiver

[httpserver.default]
address=":8000"

[storage.default]
class-name="inmemory"
workers=20
intervals=15
expire-group=604800
min-distance=1

## Vamos deixar comentado por enquanto
# [notifier.default]
# class-name="http"
# url-open="http://someservice.example.com:1467/v1/event"
# interval=60
# timeout=5
# keepalive=30
# extras={ api_key="REDACTED", app="burrow", tier="STG", fabric="mydc" }
# template-open="conf/default-http-post.tmpl"
# template-close="conf/default-http-delete.tmpl"
# method-close="DELETE"
# send-close=true
# threshold=1
Enter fullscreen mode Exit fullscreen mode

Com o arquivo docker-compose.yml criado e o arquivo de configuração burrow.toml alterado com os endereços de seus clusters, podemos subir as duas aplicações:

$ docker-compose -f docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

Agora que temos os dois containers rodando, vamos configurar o Prometheus para que este capture as métricas.

No arquivo de configuração do Prometheus (vim /srv/prometheus-2.12.0.linux-amd64/prometheus.yml), você deve adicionar as seguintes linhas:

- job_name: 'burrow'
    static_configs:
    - targets: ['127.0.0.1:8090']
Enter fullscreen mode Exit fullscreen mode

O IP 127.0.0.1 deve ser substituído pelo o IP do servidor que está executando o container que subimos acima.

Para o Prometheus reconhecer tais configurações precisamos realizar um reload no serviço:

# systemctl reload prometheus
Enter fullscreen mode Exit fullscreen mode

Agora vamos importar o dashboard no Grafana. O link abaixo é o dash específico para essas métricas:
https://grafana.com/grafana/dashboards/11963

Quando tiver importando o dash acima e tudo tiver ocorrido bem você verá algo parecido com imagem abaixo:
Alt Text

Lembram que eu havia comentado acima que iriamos utilizar o repositório que eu forkei? Pois bem, se você analisar o dash que importamos vai ver que tem um campo na tabela chamado Consumer client. Foi esse campo que adicionei no PR que abri e o dono do repositório nunca aceitou. Com essa informação sabemos qual é o IP do servidor que está consumindo naquela especifica partição.

Conclusão

O sucesso para que o seu cluster Apache Kafka (ou qualquer outra aplicação) esteja 100% disponível e seja 100% confiável é ter uma stack madura de monitoração. Como mostrado nesse artigo, não é necessário gastar uma bala com licenças em softwares de monitoração achando que tal software vai fazer mágica para você. Com ferramentas Open Source somos capaz de tirar o melhor que cada uma tem a oferecer e montar uma stack muito madura de monitoração e alertas.

Top comments (0)