Casos de Uso do Redis: Cache, Filas e Rate Limiting

Backend2026-10-06TryQuickToolBox

Você construiu uma aplicação web que funciona bem com alguns usuários, mas conforme o tráfego cresce, você percebe lentidão no carregamento de páginas, tarefas em segundo plano duplicadas e APIs sendo sobrecarregadas por clientes abusivos. Esses são problemas clássicos de escalabilidade que o Redis pode resolver de forma elegante. O Redis é um armazenamento de dados em memória que se destaca em três tarefas principais: cache, filas e rate limiting. Neste artigo, exploraremos cada caso de uso com exemplos práticos e boas práticas.

Por que usar Redis para esses casos de uso?

O Redis armazena dados na memória, tornando-o incrivelmente rápido — muitas vezes com tempos de resposta abaixo de milissegundos. Ele suporta estruturas de dados ricas como strings, listas, conjuntos, conjuntos ordenados e hashes, que se mapeiam naturalmente para cache, filas e rate limiting. Ele também oferece operações atômicas, pub/sub e opções de persistência, tornando-o uma ferramenta versátil para desenvolvedores backend.

1. Cache com Redis

Cache é o caso de uso mais comum do Redis. Ao armazenar dados acessados com frequência no Redis, você reduz a carga do banco de dados e acelera as respostas.

Como funciona o cache

Quando uma requisição chega, verifique se os dados existem no Redis. Se sim (cache hit), retorne-os diretamente. Se não (cache miss), busque no banco de dados, armazene no Redis com um tempo de expiração e retorne. Esse padrão é chamado de cache-aside.

// Exemplo em Node.js usando ioredis
const Redis = require('ioredis');
const redis = new Redis();

async function getUser(userId) {
  const cacheKey = `user:${userId}`;
  const cached = await redis.get(cacheKey);
  if (cached) return JSON.parse(cached);

  const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]);
  await redis.set(cacheKey, JSON.stringify(user), 'EX', 3600); // TTL de 1 hora
  return user;
}

Boas práticas para cache

Estratégias de invalidação de cache

Invalidação é difícil. Estratégias comuns incluem:

2. Filas com Redis

Filas desacoplam tarefas demoradas do ciclo de requisição-resposta. Por exemplo, enviar e-mails, processar imagens ou gerar relatórios podem ser feitos de forma assíncrona.

Implementando uma fila simples

Listas do Redis são perfeitas para filas. Use LPUSH para adicionar tarefas à esquerda e BRPOP para bloquear e remover da direita (FIFO).

// Produtor: adiciona tarefa
await redis.lpush('email_queue', JSON.stringify({ to: 'user@example.com', subject: 'Bem-vindo' }));

// Consumidor: processa tarefa (em um worker)
while (true) {
  const job = await redis.brpop('email_queue', 0); // 0 = bloqueia indefinidamente
  const { to, subject } = JSON.parse(job[1]);
  await sendEmail(to, subject);
}

Filas confiáveis com BRPOPLPUSH

Para evitar perder tarefas se um worker travar, use BRPOPLPUSH para mover atomicamente a tarefa para uma lista de processamento. Após o processamento bem-sucedido, remova-a da lista de processamento. Se o worker morrer, outro worker pode recuperar tarefas da lista de processamento.

const job = await redis.brpoplpush('email_queue', 'processing_queue', 0);
try {
  // processa tarefa
  await redis.lrem('processing_queue', 1, job);
} catch (err) {
  // trata erro, talvez recolocar na fila
}

Bibliotecas dedicadas a filas

Para produção, considere bibliotecas como Bull (Node.js), RQ (Python) ou Sidekiq (Ruby). Elas fornecem retentativas, agendamento e monitoramento prontos para uso.

3. Rate Limiting com Redis

Rate limiting protege sua API contra abusos e garante uso justo. As operações atômicas do Redis o tornam ideal para contar requisições.

Rate limiting de janela fixa

Incremente um contador para cada usuário por janela de tempo. Se a contagem exceder o limite, rejeite a requisição.

async function isAllowed(userId, limit = 100, windowSec = 60) {
  const key = `rate:${userId}:${Math.floor(Date.now() / 1000 / windowSec)}`;
  const count = await redis.incr(key);
  if (count === 1) await redis.expire(key, windowSec);
  return count