Camadas L1-L3, cache-aside, TTL, invalidacao, Redis keys
PADRAO CACHE-ASIDE (Lazy Loading)
O padrao mais comum e seguro. A aplicacao gerencia o cache manualmente.
async function getUser(userId) {
const cacheKey = user:${userId}
// 1. Tentar cache primeiro
const cached = await redis.get(cacheKey)
if (cached) return JSON.parse(cached)
// 2. Cache miss: buscar no banco
const user = await db.User.findById(userId)
if (!user) return null
// 3. Popular cache com TTL
await redis.setex(cacheKey, 3600, JSON.stringify(user)) // TTL: 1 hora
return user
}
// Invalidar ao atualizar
async function updateUser(userId, data) {
await db.User.update(userId, data)
await redis.del(user:${userId}) // invalida o cache
}
Vantagens: simples, resiliente (app funciona sem cache), dado fresco apos invalidacao. Desvantagem: primeiro acesso sempre vai ao banco (cold start).
TTL — TIME TO LIVE
Definir TTL adequado por tipo de dado:
Dados altamente volateis (TTL: 30s - 5min):
Dados moderadamente volateis (TTL: 5min - 1h):
Dados pouco volateis (TTL: 1h - 24h):
Dados quase estaticos (TTL: 24h - 7d):
Regras de TTL:
Nunca usar TTL infinito para dados que podem mudar
TTL deve ser menor que o tempo maximo aceitavel de dado desatualizado
Adicionar jitter (variacao aleatoria de +-10%) para evitar thundering herd
// TTL com jitter const ttl = 3600 + Math.floor(Math.random() * 360) // 1h +- 6min
NOMENCLATURA DE CHAVES REDIS
Padrao: namespace:entidade:identificador:campo_opcional
user:42 → dados completos do usuario 42 user:42:permissions → permissoes do usuario 42 session:abc123 → dados de sessao rate:login:192.168.1.1 → contador de rate limit por IP cache:search:eletronicos:p1 → resultado de busca paginado
Regras:
: (nao . ou -)INVALIDACAO DE CACHE
Estrategia 1 — Invalidacao imediata (TTL + delete explicito):
Ao atualizar dado: redis.del(cacheKey)
Mais consistente, mais codigo para manter.
Estrategia 2 — TTL apenas (eventual consistency): Cache expira naturalmente. Dado pode estar desatualizado ate expirar. Adequado para dados onde atraso e aceitavel (catalogo, precos).
Estrategia 3 — Cache com versao (cache busting):
Incluir versao/hash na chave. Ao atualizar, nova chave, cache antigo expira por TTL.
user:42:v2 — ao mudar schema, incrementar versao globalmente.
Armadilhas:
CACHE DE RESPOSTAS HTTP
Cache-Control headers: // Dado publico, cacheavel por CDN por 1 hora, revalidar apos 30min res.set('Cache-Control', 'public, max-age=3600, stale-while-revalidate=1800')
// Dado privado (por usuario), nao cacheavel por CDN res.set('Cache-Control', 'private, max-age=300')
// Sem cache (dados sensiveis ou altamente volateis) res.set('Cache-Control', 'no-store')
ETag para revalidacao:
const etag = crypto.createHash('md5').update(JSON.stringify(data)).digest('hex')
res.set('ETag', "${etag}")
if (req.headers['if-none-match'] === "${etag}") return res.sendStatus(304)
CHECKLIST