“`html
Arquitetura e operação
Dominando a arquitetura de Prometheus
Eu gosto de pensar no Prometheus como um sistema com responsabilidades bem definidas: coletar,
armazenar, consultar e alertar. Quando essas peças ficam claras,
a operação deixa de ser “tentativa e erro” e vira engenharia.
Modelagem de métricas
Retenção e performance
PromQL
Alertas e rotas
1) O mapa mental da arquitetura: coleta → armazenamento → consulta → alertas
A arquitetura do Prometheus é simples por fora, mas precisa de disciplina por dentro. Em alto nível, o fluxo é:
Coleta (scrape)
- O Prometheus faz requisições HTTP para cada target.
- Ele lê um endpoint (tipicamente
/metrics) e ingere métricas no formato esperado. - A cadência é controlada por job e intervalos.
Armazenamento (time series)
- As métricas viram séries temporais indexadas por nome + conjunto de rótulos.
- Há regras de retenção que afetam disco, desempenho e comportamento de consultas.
- O disco local vira parte crítica do “SLO” do sistema de observabilidade.
Consulta (PromQL)
- Você pergunta ao banco de séries temporais por agregações, filtros e funções.
- O desempenho depende do que você busca e do volume de dados.
Alertas (e fluxo de notificação)
- O Prometheus avalia expressões e decide o estado do alerta.
- O envio para o “mundo externo” costuma ser via Alertmanager.
- Separar regras de alerta e roteamento reduz ruído operacional.
Se você entender onde o custo aparece (scrape, cardinalidade, retenção, consultas), você consegue otimizar com intenção — não com sorte.
2) Coleta e configurações: jobs, targets e qualidade do endpoint
A configuração de scrape é onde a maioria dos sistemas “começa a escorregar”. Eu trato como contrato: se o endpoint
não é estável, o Prometheus vai amplificar o problema com volume e tempo.
Boas práticas de scrape
- Evite scrapear tudo no mesmo intervalo; use intervalos compatíveis com a dinâmica do recurso.
- Padronize rótulos: nome de job, ambiente e origem com consistência.
- Trate timeouts: endpoints lentos viram “buracos” de dados e aumentam carga.
Validação do endpoint
- Confirme que o formato de métricas é compatível e não muda por deploy.
- Garanta que métricas críticas não dependem de inicialização lenta.
- Use healthchecks e métricas internas para observar o próprio Prometheus.
Antes de aumentar cardinalidade ou quantidade de targets, valide: latency do endpoint, taxa de erros e estabilidade do conjunto de rótulos.
3) Modelagem de métricas: cardinalidade, rótulos e consistência
Dominando a arquitetura, você controla o tamanho do problema. O Prometheus sofre principalmente por um fator:
cardinalidade (quantidade de séries temporais geradas pelos rótulos).
O que eu evito
- Rótulos com valores de alta variação (ex.: IDs únicos por requisição).
- “Concatenação” de semântica em rótulos quando já existe métrica para isso.
- Rótulos inconsistentes entre serviços, que quebram agregações e aumentam confusão.
O que eu prefiro
- Rótulos estáveis e com significado operacional: env, service, region, status.
- Design de métricas com “grupos” por finalidade (latência, taxa, erros, capacidade).
- Usar histogramas/summary com propósito (e entender o impacto em armazenamento e queries).
Uma regra prática que eu sigo: um rótulo deve ajudar a responder uma pergunta.
Se ele não responde, ele vira custo. E custo acumulado vira incidente: disco, performance e retrabalho.
4) Um exemplo completo: scrape + regras e consultas que não matam o servidor
Abaixo eu mostro um exemplo de configuração e, junto, como eu penso nas consultas para manter performance e
consistência. Repare na intenção: limitar cardinalidade, controlar a cadência e escrever PromQL com responsabilidade.
# prometheus.yml (exemplo enxuto e comum em projetos reais)
global:
scrape_interval: 15s
evaluation_interval: 30s
scrape_configs:
- job_name: "api-service"
metrics_path: /metrics
scheme: http
scrape_interval: 10s
scrape_timeout: 3s
static_configs:
- targets:
- "api-01:8080"
- "api-02:8080"
relabel_configs:
# Padroniza ambiente via label estável (ex.: para evitar variações)
- source_labels: [__address__]
target_label: instance
regex: "([^:]+):.*"
replacement: "$1"
action: replace
- job_name: "node-exporter"
metrics_path: /metrics
scrape_interval: 30s
scrape_timeout: 5s
static_configs:
- targets:
- "node-01:9100"
- "node-02:9100"
# alerts.yml (regras) - exemplo ilustrativo
groups:
- name: api-latency
rules:
- alert: ApiP95LatencyHigh
expr: histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket{job="api-service"}[5m])) by (le))
> 0.6
for: 3m
labels:
severity: page
annotations:
summary: "P95 da latência da API acima do esperado"
description: "A latência P95 ficou acima de 600ms por 3 minutos (job=api-service)."
- alert: ApiErrorRateHigh
expr: (sum(rate(http_requests_total{job="api-service", status=~"5.."}[5m])) /
sum(rate(http_requests_total{job="api-service"}[5m]))) > 0.02
for: 2m
labels:
severity: page
annotations:
summary: "Taxa de erro 5xx acima de 2%"
description: "A taxa de erros 5xx ultrapassou 2% por 2 minutos."
Por que esse PromQL é “amigável”?
- Usa janelas coerentes ([5m]) para reduzir ruído e custo de recomputação.
- Agrega com
sum(... ) by (...)antes de comparar com limiares. - Evita varrer o universo sem filtros por job e por conjuntos previsíveis.
Onde eu tomo cuidado
- Histogramas: entenda o número de buckets e a quantidade de séries por rótulo.
- Expressões muito “amplas”: sem filtros, o custo cresce rápido com cardinalidade.
- Alertas com for curto demais: vira flapping e desgaste operacional.
Quer continuar aprofundando?
No yurideveloper.com.br eu escrevo posts com abordagem prática e técnica: arquitetura, operação, troubleshooting
e melhores decisões para sistemas de observabilidade.
“`
Sou Apaixonado pela programação e estou trilhando o caminho de ter cada diz mais conhecimento e trazer toda minha experiência vinda do Design para a programação resultando em layouts incríveis e idéias inovadoras! Conecte-se Comigo!