Introdução ao Redis: chave-valor em memória
1. O que é Redis e por que usá-lo?
1.1. Definição: banco de dados chave-valor em memória
Redis (Remote Dictionary Server) é um banco de dados NoSQL do tipo chave-valor que armazena todos os dados primariamente na memória RAM. Diferente de bancos relacionais como PostgreSQL ou MySQL, que persistem dados em disco e usam memória apenas como cache temporário, o Redis trabalha com estruturas de dados na memória principal, oferecendo latências na ordem de microssegundos para operações de leitura e escrita.
1.2. Diferenças fundamentais entre Redis e bancos relacionais
| Característica | Bancos Relacionais (PostgreSQL) | Redis |
|---|---|---|
| Armazenamento | Disco (HD/SSD) | Memória RAM |
| Modelo de dados | Tabelas, linhas, colunas | Chave-valor, hashes, listas |
| Linguagem de consulta | SQL (estruturada) | Comandos próprios (não-SQL) |
| ACID | Transações completas | Garantias mais simples |
| Velocidade | Milissegundos | Microssegundos |
| Persistência | Garantida por padrão | Opcional (RDB/AOF) |
1.3. Casos de uso típicos
Redis é ideal para cenários que exigem alta performance e baixa latência:
- Cache de consultas SQL: armazenar resultados de
SELECTpesados - Gerenciamento de sessões: sessões de usuário em aplicações web
- Filas de tarefas: processamento assíncrono com Lists
- Contadores: likes, visualizações, métricas em tempo real
- Rate limiting: controle de requisições por IP
2. Instalação e primeiros passos
2.1. Instalação local e via Docker
Instalação local (Ubuntu/Debian):
sudo apt update
sudo apt install redis-server
sudo systemctl start redis
Usando Docker (recomendado para testes rápidos):
docker run --name meu-redis -d -p 6379:6379 redis:7-alpine
2.2. Acessando o Redis com redis-cli
redis-cli
127.0.0.1:6379> PING
PONG
2.3. Comandos básicos: SET, GET, DEL, EXISTS
127.0.0.1:6379> SET usuario:1 "João Silva"
OK
127.0.0.1:6379> GET usuario:1
"João Silva"
127.0.0.1:6379> EXISTS usuario:1
(integer) 1
127.0.0.1:6379> DEL usuario:1
(integer) 1
127.0.0.1:6379> GET usuario:1
(nil)
3. Estruturas de dados fundamentais
3.1. Strings: armazenamento de valores simples e contadores
127.0.0.1:6379> SET contador:visitas 0
OK
127.0.0.1:6379> INCR contador:visitas
(integer) 1
127.0.0.1:6379> INCRBY contador:visitas 10
(integer) 11
127.0.0.1:6379> GET contador:visitas
"11"
3.2. Hashes: objetos com múltiplos campos
127.0.0.1:6379> HSET usuario:100 nome "Maria" idade 30 email "maria@email.com"
(integer) 3
127.0.0.1:6379> HGET usuario:100 nome
"Maria"
127.0.0.1:6379> HGETALL usuario:100
1) "nome"
2) "Maria"
3) "idade"
4) "30"
5) "email"
6) "maria@email.com"
3.3. Lists: filas e pilhas
127.0.0.1:6379> LPUSH tarefas "processar_pagamento"
(integer) 1
127.0.0.1:6379> RPUSH tarefas "enviar_email"
(integer) 2
127.0.0.1:6379> LLEN tarefas
(integer) 2
127.0.0.1:6379> LPOP tarefas
"processar_pagamento"
127.0.0.1:6379> RPOP tarefas
"enviar_email"
4. Trabalhando com TTL e expiração de chaves
4.1. Comandos EXPIRE, TTL e PERSIST
127.0.0.1:6379> SET cache:consulta "resultado_importante"
OK
127.0.0.1:6379> EXPIRE cache:consulta 60
(integer) 1
127.0.0.1:6379> TTL cache:consulta
(integer) 57
127.0.0.1:6379> PERSIST cache:consulta
(integer) 1
127.0.0.1:6379> TTL cache:consulta
(integer) -1
4.2. Estratégias de expiração
Redis utiliza três estratégias para remover chaves expiradas:
- Passiva: quando uma chave expirada é acessada, Redis a remove
- Ativa: a cada 100ms, Redis testa 20 chaves aleatórias e remove as expiradas
- Lazy: durante operações de escrita, Redis verifica expiração
4.3. Exemplo prático: cache de consultas SQL com expiração automática
# Simulação: cache de resultado SELECT por 5 minutos
SET cache:select:produtos_mais_vendidos '{"dados": [{"id": 1, "nome": "Produto A"}]}'
EXPIRE cache:select:produtos_mais_vendidos 300
5. Redis como cache para bancos relacionais
5.1. Padrão cache-aside
O padrão cache-aside funciona assim:
- A aplicação verifica Redis primeiro
- Se encontrou (cache hit), retorna o valor
- Se não encontrou (cache miss), consulta o banco relacional
- Armazena o resultado no Redis com TTL
- Retorna o resultado
5.2. Estratégias de invalidação de cache
- TTL (Time-To-Live): expiração automática após período definido
- Notificações: invalidar cache quando o banco for atualizado
- Write-through: atualizar cache simultaneamente ao banco
5.3. Exemplo: cache de resultados de SELECT com GET/SET
# Fluxo completo de cache-aside no redis-cli
# 1. Tentar obter do cache
GET cache:select:cliente_123
# 2. Se retornar nil, simular consulta ao banco e armazenar
SET cache:select:cliente_123 '{"id": 123, "nome": "Carlos", "saldo": 1500.50}'
EXPIRE cache:select:cliente_123 600
# 3. Próxima consulta retorna do cache (mais rápido)
GET cache:select:cliente_123
6. Persistência no Redis: RDB e AOF
6.1. Snapshotting (RDB)
RDB cria snapshots completos dos dados em disco em intervalos configurados:
# Configuração no redis.conf
save 900 1 # Salva se pelo menos 1 chave mudou em 15 minutos
save 300 10 # Salva se pelo menos 10 chaves mudaram em 5 minutos
save 60 10000 # Salva se pelo menos 10000 chaves mudaram em 1 minuto
6.2. Append-only file (AOF)
AOF registra cada operação de escrita em um log:
# Configuração no redis.conf
appendonly yes
appendfsync everysec # Sincroniza a cada segundo (balanceado)
6.3. Comparação: quando usar RDB vs AOF vs ambos
| Aspecto | RDB | AOF | Ambos |
|---|---|---|---|
| Tamanho do arquivo | Menor | Maior | Maior |
| Recuperação | Mais rápida | Mais lenta | Flexível |
| Perda de dados | Possível (intervalo) | Mínima (segundos) | Mínima |
| Uso recomendado | Backups periódicos | Alta durabilidade | Produção crítica |
7. Redis em produção: boas práticas e limitações
7.1. Limitações de memória RAM e políticas de evicção
Redis é limitado pela RAM disponível. Quando a memória atinge o limite, políticas de evicção definem quais chaves remover:
# Configuração no redis.conf
maxmemory 1gb
maxmemory-policy allkeys-lru # Remove as chaves menos usadas recentemente
Políticas comuns:
- allkeys-lru: remove as menos usadas (recomendado para cache)
- volatile-ttl: remove as que expiram mais cedo
- noeviction: retorna erro quando a memória acaba
7.2. Monitoramento com INFO, MONITOR e SLOWLOG
# Estatísticas gerais
INFO memory
INFO stats
INFO keyspace
# Monitorar comandos em tempo real (cuidado em produção!)
MONITOR
# Ver comandos lentos (acima de 10ms por padrão)
SLOWLOG GET 10
7.3. Integração com aplicações
Python com redis-py:
import redis
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
r.set('chave', 'valor')
print(r.get('chave'))
Node.js com ioredis:
const Redis = require('ioredis');
const redis = new Redis();
await redis.set('chave', 'valor');
console.log(await redis.get('chave'));
8. Conclusão e próximos passos
Redis oferece vantagens significativas sobre bancos relacionais tradicionais em cenários que exigem baixa latência e alta throughput. Sua natureza em memória permite operações em microssegundos, enquanto estruturas de dados como Strings, Hashes e Lists resolvem problemas comuns de cache, filas e contadores com simplicidade.
Para aprofundar, explore TTL e expiração avançada, estruturas como Sets e Sorted Sets, e padrões de cache mais sofisticados. Um exercício prático imediato: implemente um cache simples que armazena resultados de uma consulta SQL por 10 minutos, usando o padrão cache-aside.
Exercício prático
Implemente o seguinte fluxo:
# 1. Simule uma consulta SQL pesada
SET cache:select:vendas_2024 '{"total": 150000, "itens": 1200}'
# 2. Defina expiração de 5 minutos
EXPIRE cache:select:vendas_2024 300
# 3. Verifique o TTL
TTL cache:select:vendas_2024
# 4. Simule um cache miss (após expiração)
GET cache:select:vendas_2024
Redis não substitui bancos relacionais, mas os complementa perfeitamente, oferecendo uma camada de desempenho que transforma a experiência do usuário final.
Referências
- Documentação oficial do Redis — Guia completo com todos os comandos, estruturas de dados e configurações do Redis.
- Redis: Cache-aside pattern — Explicação detalhada do padrão cache-aside com exemplos práticos de implementação.
- Redis Persistence (RDB e AOF) — Documentação oficial sobre as estratégias de persistência RDB e AOF.
- Usando Redis como cache para PostgreSQL — Guia oficial do PostgreSQL sobre otimização de consultas com cache externo.
- Redis Memory Eviction Policies — Documentação detalhada sobre políticas de evicção de memória no Redis.
- Tutorial Redis com Docker — Imagem oficial do Redis no Docker Hub com instruções de uso e configuração.