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:
- Baixar a versão mais estável do Prometheus ```
wget https://github.com/prometheus/prometheus/releases/download/v2.12.0/prometheus-2.12.0.linux-amd64.tar.gz
- Descompactando no diretório /srv
tar -zxvf prometheus-2.12.0.linux-amd64.tar.gz -C /srv/
- Adicionar usuário de serviço do prometheus
useradd -s /usr/sbin/nologin prometheus
- Mudar o dono da pasta do prometheus
chown prometheus:prometheus /srv/prometheus-2.12.0.linux-amd64/ -R
- Adicionar o arquivo de service do prometheus
vim /etc/systemd/system/prometheus.service
[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
- Executar o daemon-reload e iniciar o serviço
systemctl daemon-reload
systemctl start prometheus
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
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
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 .
>Nesse post irei focar na instalação do Burrow via [Docker](https://www.docker.com/). Para aqueles que preferirem executar o Burrow sem o uso do Docker, é só seguir os passos que estão descritos no [README.rd](https://github.com/linkedin/Burrow#build-and-install) 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:
alvarobacelar
/
burrow_exporter
A Prometheus Exporter for gathering Kafka consumer group info from Burrow
git clone https://github.com/alvarobacelar/burrow_exporter.git
> O repositório acima é um fork do projeto [burrow_exporter](https://github.com/shamil/burrow_exporter) criado por Shamil. Eu solicitei um [Pull Request](https://github.com/shamil/burrow_exporter/pull/1) 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 .
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:
```yaml
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
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
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
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
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']
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
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:
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)