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.
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?