Introdução aos Bancos de Dados em Memória e Sistemas de Cache
Casos de uso mais comuns
Explore cache, sessões, rate limiting, filas, leaderboards, geolocalização, pub/sub e armazenamento temporário.
Nesta aula você vai
- Mapear os padrões de uso mais frequentes de bancos em memória em produção
- Associar cada caso de uso a estruturas de dados e comandos adequados
- Antecipar riscos de consistência e invalidação em cada padrão
Casos de uso mais comuns
Objetivos
Nesta aula você vai:
- Conhecer os padrões de arquitetura que mais recorrem a dados em memória
- Relacionar cada padrão à estrutura Redis (ou equivalente) mais indicada
- Reconhecer armadilhas de cache stale, thundering herd e hot keys
Introdução
Bancos em memória não são um martelo para todos os pregos — mas há um conjunto de problemas que se repetem em praticamente todo sistema de escala média ou alta. Dominar esses padrões permite reconhecer oportunidades na sua própria arquitetura e evitar reinventar soluções frágeis com SQL ou arquivos temporários.
Esta aula organiza os casos por intenção de negócio, não por comando isolado. O comando é consequência do problema.
Conteúdo
Cache de leitura (cache-aside e read-through)
O padrão mais disseminado: reduzir carga no banco relacional ou API lenta armazenando respostas frequentes em memória.
Fluxo cache-aside:
- Aplicação tenta
GETna chave - Em caso de miss, consulta o banco
- Grava no cache com TTL
- Retorna ao cliente
| Vantagem | Risco |
|---|---|
| Banco permanece fonte de verdade | Dados desatualizados até expirar TTL |
| Degradação graciosa se cache cair | Thundering herd em miss massivo |
Comandos típicos:
SET sessao:abc123 '{"userId":1001}' EX 1800
GET sessao:abc123
Sessão e estado de usuário
Aplicações stateless (múltiplas instâncias atrás de load balancer) precisam de sessão centralizada. Redis armazena cookie de sessão → payload JSON ou hash com TTL alinhado ao tempo de logout.
HSET sessao:token-xyz user_id 1001 role "admin" last_seen 1710000000
EXPIRE sessao:token-xyz 3600
Alternativa: JWT stateless na aplicação — sem Redis — mas revogação imediata e sessões longas com dados mutáveis favorecem store em memória.
Rate limiting e controle de abuso
APIs públicas limitam requisições por IP ou por token. Contador com janela fixa ou deslizante:
# Janela fixa: incrementa e define TTL na primeira requisição
INCR ratelimit:192.168.1.1:2026-07-08T16:00
EXPIRE ratelimit:192.168.1.1:2026-07-08T16:00 60
Se o valor exceder o limite (ex.: 100), a API retorna HTTP 429. Sorted sets e scripts Lua permitem janelas deslizantes mais precisas.
Filas, Pub/Sub e processamento assíncrono
Listas como fila simples:
LPUSH fila:emails '{"to":"user@ex.com","template":"welcome"}'
BRPOP fila:emails 30
Pub/Sub para broadcast (não durável — assinantes offline perdem mensagens):
SUBSCRIBE canal:notificacoes
PUBLISH canal:notificacoes "pedido-123-pago"
Para filas duráveis com consumer groups, Redis Streams é a evolução recomendada em cenários mais exigentes.
Leaderboards, contagens e agregações em tempo real
Sorted sets (ZSET) mantêm ranking ordenado por score com complexidade logarítmica:
ZADD ranking:game 1500 "jogador_ana"
ZADD ranking:game 2200 "jogador_bruno"
ZREVRANGE ranking:game 0 9 WITHSCORES
INCR, HINCRBY e HyperLogLog (PFADD) cobrem métricas e cardinalidade aproximada com footprint mínimo.
Distributed locks e coordenação (com cautela)
Locks com SET chave valor NX EX ttl evitam processamento duplicado. Exige:
- TTL para evitar lock eterno se o processo morrer
- Valor único (UUID) para liberar só quem adquiriu
- Consciência de que failover em Redis não-Cluster pode gerar dois masters brevemente
Padrões mais seguros usam Redlock com debate na comunidade, ou ferramentas dedicadas (etcd, ZooKeeper) para coordenação crítica.
Exemplos práticos
Cenário: catálogo de produtos com pico de Black Friday.
# Cache com TTL de 5 minutos
SET produto:sku-991 "{...json...}" EX 300
# Lock leve para evitar stampede no miss (pseudopadrão)
SET lock:produto:sku-991 "worker-7" NX EX 10
Se GET produto:sku-991 retornar (nil) e dezenas de threads competirem pelo banco, o lock serializa a reconstrução — uma thread popula o cache; as demais aguardam ou retornam valor stale se configurado.
Métricas para monitorar:
INFO stats
Campos keyspace_hits e keyspace_misses alimentam taxa de acerto do cache — KPI essencial em produção.
Resumo
- Cache de leitura, sessão, rate limit, filas, rankings e locks cobrem a maioria dos deploys de Redis em produção.
- Cada caso mapeia para estruturas específicas: strings, hashes, lists, sorted sets, streams.
- TTL, invalidação e política de eviction definem consistência percebida pelo usuário.
- Pub/Sub é rápido mas não durável; filas exigem listas ou Streams conforme garantias necessárias.
- Locks distribuídos resolvem problemas reais, mas exigem disciplina e entendimento de falhas de rede e failover.