Performance e otimização

Como medir desempenho corretamente

Metodologia rigorosa para benchmark de cache — percentis de latência, warm-up, variáveis de ambiente e armadilhas comuns que distorcem resultados.

Avançado 30 min 25 pontos Leitura 0%

Nesta aula você vai

  • Aplicar metodologia correta de benchmark para sistemas de cache
  • Interpretar percentis P50, P95 e P99 e definir SLAs realistas
  • Evitar armadilhas comuns que invalidam resultados de performance

Como medir desempenho corretamente

Objetivos

Nesta aula você vai:

  • Aprender metodologia rigorosa para medir performance de cache
  • Dominar o vocabulário de percentis e SLAs de latência
  • Identificar e evitar armadilhas que produzem benchmarks enganosos

Conteúdo

A diferença entre medição e ilusão

Há uma cena recorrente na literatura técnica: o engenheiro apresenta um gráfico mostrando 1 milhão de operações por segundo, e o sistema cai na primeira segunda-feira de tráfego real. O problema raramente é a ferramenta — é a metodologia de medição.

Medir performance de cache corretamente é como crítica literária séria: não basta contar páginas; é preciso examinar contexto, nuances e o que foi deliberadamente omitido.

O que medir: as quatro dimensões

Dimensão Métrica Ferramenta
Throughput Operações por segundo (ops/s) redis-benchmark, memtier_benchmark
Latência Tempo por operação (ms) redis-cli --latency, histogramas
Utilização de recursos CPU, RAM, rede, disco INFO, top, iostat, Prometheus
Taxa de erro Timeouts, conexões recusadas Logs, métricas de aplicação

Nenhuma dimensão isolada conta a história completa. 500.000 ops/s com P99 de 200 ms é inaceitável para checkout; 50.000 ops/s com P99 de 2 ms pode ser excelente.

Percentis: o vocabulário obrigatório

Percentil Definição Analogia
P50 (mediana) 50% das requisições são mais rápidas A experiência do usuário "típico"
P95 95% das requisições abaixo deste valor Usuários em horário de pico
P99 99% das requisições abaixo deste valor A cauda longa — onde SLAs quebram
P99.9 99,9% abaixo deste valor Outliers extremos — incidentes raros
Exemplo: 1000 requisições ordenadas por latência

Req #1:    0,1 ms  ─┐
Req #500:  0,3 ms   ├─ P50 = 0,3 ms
Req #950:  1,2 ms   ├─ P95 = 1,2 ms
Req #990:  8,5 ms   ├─ P99 = 8,5 ms
Req #999: 45,0 ms   └─ P99.9 = 45,0 ms

Média: 1,8 ms  ← ENGANOSA (puxada pelos outliers)

Regra: defina SLAs em percentis, nunca em média.

# Medir latência em tempo real
redis-cli --latency -h localhost -p 6379

# Histórico com percentis a cada segundo
redis-cli --latency-history -h localhost -p 6379 -i 1

# Latência intrínseca do servidor (sem rede)
redis-cli --intrinsic-latency 100

Metodologia de benchmark: passo a passo

1. Reproduza o ambiente de produção

Variável Por que importa
Mesma versão do Redis/Valkey Comportamento muda entre versões
Mesmo hardware (CPU, RAM, rede) Resultados não transferem entre máquinas
Mesmo dataset (tamanho e distribuição) Cache vazio vs quente muda tudo
Mesma configuração (maxmemory, AOF, etc.) Persistência altera P99 drasticamente
Mesma topologia (standalone vs cluster) Sharding adiciona latência de rede

2. Warm-up obrigatório

Cache frio ≠ cache quente. Antes de medir, execute operações suficientes para:

  • Popular o dataset representativo
  • Estabilizar JIT/compilação (em clientes Java)
  • Aquecer conexões TCP (connection pooling)
# Warm-up: 50.000 operações antes do benchmark real
redis-benchmark -h localhost -p 6379 -t set,get -n 50000 -q

# Benchmark real
redis-benchmark -h localhost -p 6379 -t set,get -n 1000000 -c 50 -d 256 -q

3. Parâmetros do redis-benchmark explicados

redis-benchmark \
  -h localhost \          # Host
  -p 6379 \               # Porta
  -c 50 \                 # Conexões paralelas (clientes simultâneos)
  -n 1000000 \            # Total de requisições
  -d 256 \                # Tamanho do valor em bytes
  -t set,get \            # Tipos de operação
  -P 16 \                 # Pipeline: 16 comandos por round-trip
  --csv                   # Saída em CSV para análise
Parâmetro Impacto
-c (conexões) Muito baixo → subutiliza servidor; muito alto → contenção no cliente
-d (tamanho) Valores maiores → menos ops/s, mais latência
-P (pipeline) Aumenta throughput mas não reflete latência real por operação
-n (total) Muito baixo → resultado estatisticamente insignificante

4. Separe throughput de latência

redis-benchmark mede throughput. Para latência real por operação (sem pipeline), use ferramentas dedicadas:

# memtier_benchmark (Redis Labs) — gera histogramas de latência
memtier_benchmark -s localhost -p 6379 \
  --ratio=1:1 \
  --test-time=60 \
  --data-size=256 \
  --clients=50 \
  --threads=4 \
  --latency-history \
  --print-percentiles=50,95,99,99.9

Armadilhas clássicas

Armadilha Por que distorce Correção
Benchmark em localhost Elimina latência de rede real Teste na mesma VPC/subnet de produção
Dataset vazio (cold cache) Infla artificialmente ops/s Warm-up com dataset representativo
Pipeline sem declarar Mostra throughput irreal Meça com e sem pipeline, declare qual
Máquina compartilhada CPU steal time distorce Máquina dedicada ou container isolado
Apenas GET (sem SET) Leitura pura é mais rápida Use ratio realista (ex.: 80% GET, 20% SET)
Ignorar persistência AOF fsync altera P99 Teste com mesma config de persistência
Benchmark curto (< 30s) Não captura GC, defrag, BGSAVE Execute por 5–15 minutos
Cliente e servidor no mesmo host Compete por CPU/RAM Separe em hosts distintos

Exemplo prático: relatório de benchmark

#!/bin/bash
# benchmark-report.sh — metodologia correta

HOST="redis.prod.internal"
PORT=6379
DURATION=300  # 5 minutos

echo "=== Configuração do servidor ==="
redis-cli -h $HOST -p $PORT INFO server | grep redis_version
redis-cli -h $HOST -p $PORT INFO memory | grep used_memory_human
redis-cli -h $HOST -p $PORT CONFIG GET appendonly
redis-cli -h $HOST -p $PORT CONFIG GET maxmemory

echo "=== Warm-up (60s) ==="
redis-benchmark -h $HOST -p $PORT -t set,get -n 500000 -c 50 -d 256 -q

echo "=== Benchmark principal (${DURATION}s) ==="
memtier_benchmark -s $HOST -p $PORT \
  --ratio=4:1 \
  --test-time=$DURATION \
  --data-size=512 \
  --clients=50 \
  --threads=4 \
  --latency-history \
  --print-percentiles=50,95,99,99.9

echo "=== Latência contínua (30s) ==="
redis-cli -h $HOST -p $PORT --latency-history -i 1 | head -30

Definindo SLAs realistas

Tier de serviço P50 P95 P99 Exemplo
Crítico (pagamento) < 1 ms < 5 ms < 10 ms Autorização de cartão
Importante (sessão) < 2 ms < 10 ms < 25 ms Validação de sessão
Tolerante (cache) < 5 ms < 25 ms < 100 ms Cache de catálogo

Monitoramento contínuo em produção

Benchmark pontual valida capacidade; monitoramento contínuo detecta degradação:

# Métricas Prometheus via redis_exporter
# Queries úteis no Grafana:

# P99 de latência de comando
histogram_quantile(0.99, rate(redis_commands_duration_seconds_bucket[5m]))

# Taxa de comandos por segundo
rate(redis_commands_processed_total[1m])

# Memória utilizada vs maxmemory
redis_memory_used_bytes / redis_memory_max_bytes

Resumo

  • Meça throughput, latência por percentil, recursos e taxa de erro — nunca apenas um
  • P50, P95 e P99 são o vocabulário de SLAs; média é enganosa
  • Warm-up, ambiente representativo e duração adequada são obrigatórios
  • Pipeline infla throughput — declare quando usá-lo e meça latência separadamente

Para refletir

"Um benchmark sem metodologia é ficção. Um benchmark com metodologia é engenharia."

Qual armadilha você já cometeu (ou viu cometer) em apresentações de performance?