Casos de Uso do Redis: Cache, Filas e Rate Limiting
Você construiu uma aplicação web que está ganhando tração, mas agora cada carregamento de página acessa o banco de dados, tarefas em segundo plano estão se acumulando e alguns usuários estão sobrecarregando sua API. Você precisa de um armazenamento de dados em memória rápido para lidar com esses desafios. O Redis é a solução ideal para cache, filas e rate limiting. Neste artigo, exploraremos esses três casos de uso principais com exemplos práticos e boas práticas.
Por que Redis para Cache, Filas e Rate Limiting?
O Redis é um armazenamento de chave-valor em memória conhecido por sua velocidade e versatilidade. Ele suporta estruturas de dados ricas como strings, listas, conjuntos, conjuntos ordenados e hashes, tornando-o ideal para diversas tarefas. Suas operações atômicas e capacidades de pub/sub ampliam ainda mais sua utilidade. Seja para reduzir a carga do banco de dados, desacoplar serviços ou proteger APIs, o Redis oferece um kit de ferramentas simples, mas poderoso.
1. Cache com Redis
O cache é o caso de uso mais comum do Redis. Ao armazenar dados acessados com frequência na memória, você reduz a latência e a carga do banco de dados. O recurso TTL (time-to-live) do Redis expira automaticamente dados obsoletos.
Como Implementar o Cache
- Verifique o cache: Antes de consultar o banco de dados, verifique se os dados existem no Redis.
- Em caso de cache miss: Busque no banco de dados e armazene o resultado no Redis com um tempo de expiração.
- Em caso de cache hit: Retorne os dados em cache diretamente.
Aqui está um exemplo em Python usando redis-py:
import redis
import json
r = redis.Redis(host='localhost', port=6379, db=0)
def get_user(user_id):
cache_key = f"user:{user_id}"
cached = r.get(cache_key)
if cached:
return json.loads(cached)
# Simula busca no BD
user = fetch_user_from_db(user_id)
r.setex(cache_key, 3600, json.dumps(user)) # Cache por 1 hora
return user
Boas Práticas para Cache
- Defina TTLs apropriados: Equilibre a atualidade e a taxa de acertos. TTLs curtos para dados voláteis, mais longos para conteúdo estático.
- Use invalidação de cache: Quando os dados mudarem, exclua ou atualize a chave de cache para evitar leituras obsoletas.
- Lide com cache stampede: Use locks ou expiração antecipada probabilística para evitar que muitas requisições atinjam o banco de dados simultaneamente em caso de cache miss.
- Monitore a taxa de acertos: Busque uma alta taxa de acertos (por exemplo, >80%) para garantir que o cache seja eficaz.
2. Filas com Redis
Listas e conjuntos ordenados do Redis permitem filas de mensagens simples, mas robustas. Elas são perfeitas para tarefas em segundo plano, filas de tarefas e processamento de eventos. Diferentemente de brokers de mensagens dedicados, as filas do Redis são leves e fáceis de configurar.
Implementando uma Fila Básica
Use LPUSH para adicionar tarefas e BRPOP para consumi-las de forma bloqueante:
# Produtor
r.lpush('job_queue', json.dumps({'task': 'send_email', 'to': 'user@example.com'}))
# Consumidor
while True:
_, job = r.brpop('job_queue', timeout=30)
if job:
process_job(json.loads(job))
Filas Avançadas com Conjuntos Ordenados
Para tarefas atrasadas ou filas de prioridade, use conjuntos ordenados com timestamps como scores. Consumidores buscam tarefas com scores