Bancos chave-valor
O modelo mais simples e mais rápido, com o Redis e suas estruturas de dados como referência.
As decisões com um banco chave-valor são cinco: para que usá-lo, como nomear e expirar as chaves, como configurar a persistência e a memória, como fazer operações de vários passos e qual produto escolher.
Para que usar
| Uso | Estrutura | Por que o Redis | Cuidado |
|---|---|---|---|
| Cache | String ou hash, com expiração | Leitura rápida, despejo automático | Ver o tópico de cache |
| Sessões | String ou hash, com expiração | Toda instância lê a mesma sessão | Persistência, ou aceitar deslogar todos numa queda |
| Contadores e limites de requisições | String com INCR e expiração | Atômico e rápido | Ver o tópico de limite de requisições |
| Placares | Sorted set | Ordenação mantida a cada ponto | Um placar por período, com expiração |
| Travas distribuídas | SET chave valor NX PX | Atômico, com expiração | Liberar só a própria trava; não é garantia absoluta (ver abaixo) |
| Filas | List, ou stream com grupos de consumidores | Simples, já instalado | Para filas sérias, ver o tópico de filas |
| Contagem de distintos | HyperLogLog | 12 KB por contador, com erro de cerca de 1% | Aproximado por definição |
| Dados de negócio principais | — | — | Não: fique no banco relacional |
Chaves e expiração
| Prática | Por quê |
|---|---|
Prefixos com dois-pontos: sessao:abc, placar:2026-46 | Organização, e SCAN por padrão |
Expiração em tudo que é temporário (EX, PX, EXPIRE) | Sem ela, a memória só cresce |
| Variação aleatória na expiração de chaves criadas juntas | Evita que expirem todas no mesmo instante |
| Valores pequenos, divididos em várias chaves se preciso | Comandos sobre valores enormes travam o servidor |
SCAN e UNLINK, nunca KEYS e DEL de chaves gigantes | No teste, o KEYS fez outro cliente esperar 308 ms; o SCAN, 6 ms |
Persistência e memória
Configure de acordo com o uso, e não deixe no padrão por acaso:
| Uso | Persistência | Política de memória |
|---|---|---|
| Só cache | Nenhuma, ou fotografias | allkeys-lru ou allkeys-lfu: apagar é o comportamento esperado |
| Sessões, carrinhos, contadores | AOF com everysec | noeviction ou volatile-lru (só chaves com expiração podem sair) |
| Dados que não podem perder nada | AOF com always, e réplica | noeviction |
| Cache e dados no mesmo Redis | — | Evite: separe em duas instâncias com configurações diferentes |
Os números do teste do nível Conceito resumem a troca. A configuração padrão perdeu as 10 mil gravações numa queda logo depois delas. O AOF com everysec sobreviveu à queda do processo e custou quase nada (116 mil contra 117 mil gravações por segundo). O always custou cinco vezes menos vazão. E o allkeys-lru, ótimo para cache, apagou 65 mil chaves em silêncio quando a memória encheu.
Réplicas e o Redis Sentinel (ou o Redis Cluster) cuidam da disponibilidade: uma réplica assume se o principal cair. A replicação é assíncrona, então o principal pode confirmar uma gravação e cair antes de passá-la à réplica. O comando WAIT espera a confirmação das réplicas, quando isso importa.
Operações de vários passos
| Necessidade | Ferramenta |
|---|---|
| Um comando atômico resolve | INCR, HINCRBY, ZINCRBY, SET ... NX, GETDEL: prefira sempre |
| Vários comandos sem intercalação, sem decisões no meio | MULTI e EXEC |
| Ler, decidir e gravar de forma atômica | Script em Lua (EVAL) ou funções (FCALL) |
| Gravar só se a chave não mudou desde a leitura | WATCH, MULTI e EXEC: a transação falha se a chave mudou |
| Muitos comandos independentes, rápido | Pipeline (sem atomicidade): 7 vezes mais rápido no teste |
Travas distribuídas
A trava com SET trava:pedido:981 <id-aleatório> NX PX 30000 é comum e tem dois erros clássicos:
- Liberar a trava de outro. Se a trava expirou enquanto o dono ainda trabalhava e outro processo a pegou, um
DELsimples apaga a trava do outro. A liberação certa confere o valor antes de apagar, num script em Lua. - Confiar nela para correção absoluta. Uma pausa longa do processo (coletor de lixo, máquina virtual suspensa) pode durar mais que a expiração, e dois processos se acham donos ao mesmo tempo. Para operações em que isso não pode acontecer, combine a trava com uma conferência no próprio banco, como um número de versão crescente gravado junto com o dado.
Qual produto
| Produto | Características |
|---|---|
| Redis | O mais completo em estruturas; desde a versão 8, de novo com licença de código aberto (AGPL), além das licenças anteriores |
| Valkey | Derivado de código aberto do Redis 7.2, mantido pela Linux Foundation; compatível com os clientes do Redis |
| Memcached | Só chave-valor simples, sem persistência; vários núcleos por processo; bom só para cache |
| Serviços gerenciados (ElastiCache, MemoryDB, Upstash, Azure Cache) | Sem operar servidores; verifique a persistência e o modelo de cobrança |
| DynamoDB | Chave-valor e documentos em disco, gerenciado e durável, com escala horizontal; outra categoria de latência e de preço |
Resumo da decisão
- Redis para o que é acessado pela chave e cabe na memória; dados de negócio principais no relacional.
- A estrutura certa para cada caso: hash, set, sorted set, stream.
- Comandos atômicos em vez de ler, calcular e gravar.
- Pipeline para muitos comandos;
SCAN, nuncaKEYS. - Expiração em tudo que é temporário.
- Persistência e política de memória escolhidas pelo uso: cache e dados em instâncias separadas.
O próximo nível mostra um placar com sorted set nas cinco linguagens, com pontos simultâneos.
Prompts para aprofundar
Ao abrir no ChatGPT ou no Claude, o prompt é enviado ao serviço escolhido pela URL e também fica copiado na sua área de transferência.
Usar o Redis no meu sistema
Quero decidir o que guardar no Redis no meu sistema. Pergunte o que o sistema faz, quais dados são acessados pela chave, o volume e o quanto cada dado pode ser perdido ou reconstruído. Para cada uso candidato, recomende se vai para o Redis ou para o banco principal, a estrutura de dados, a expiração, e a configuração de persistência e memória. No final, diga se faz sentido ter mais de uma instância.
Travas distribuídas com Redis
Preciso de uma trava distribuída para garantir que só um processo faça uma tarefa por vez. Pergunte qual linguagem eu uso, o que a tarefa faz e o que acontece se dois processos a fizerem ao mesmo tempo. Explique: 1. A trava com SET NX PX e um identificador aleatório. 2. A liberação com conferência do dono, num script em Lua. 3. O que acontece quando o processo demora mais que a expiração. 4. Por que a trava sozinha não garante correção absoluta, e como um número de versão no banco completa a proteção. 5. Alternativas: travas consultivas do PostgreSQL e filas com um consumidor só.
Redis, Valkey, Memcached ou DynamoDB
Estou escolhendo um banco chave-valor para o meu sistema. Pergunte para que ele vai servir, o volume de dados, a necessidade de durabilidade, a nuvem que eu uso e se prefiro operar servidores ou usar um serviço gerenciado. Compare para o meu caso Redis, Valkey, Memcached, um Redis gerenciado e o DynamoDB quanto a estruturas de dados, durabilidade, escala, licença, operação e custo. Recomende uma opção.