search

Estratégia de Caching: Redis, CDN, Cache do Navegador e Cache Invalidation na prática

Estratégia de Caching: Redis, CDN, Cache do Navegador e Cache Invalidation na prática

Estratégia de Caching: Redis, CDN, Cache do Navegador e Cache Invalidation

Uma Estratégia de Caching bem desenhada é um dos caminhos mais diretos para reduzir latência, economizar recursos e aumentar a resiliência de plataformas digitais.

Estratégia de Caching Ao mesmo tempo, cache é uma fonte comum de incidentes: conteúdo desatualizado, inconsistência entre sistemas, falhas de autenticação, vazamento de dados e picos de carga quando o cache expira (cache stampede).

Este guia organiza o tema por camadas — CDN, cache do navegador e Redis — e fecha com o componente mais sensível: cache invalidation (invalidação de cache). A ideia é sair da teoria e chegar em decisões práticas e verificáveis.


1) O que é uma Estratégia de Caching (e por que “só ligar cache” falha)

Cache não é apenas “guardar uma resposta para reutilizar depois”. Em arquitetura moderna, cache envolve:

  • Escopo: quem pode ver o conteúdo (público, usuário, tenant, região).
  • Camada: navegador, CDN, edge, aplicação, banco.
  • Política de expiração: TTL, revalidação, stale-while-revalidate.
  • Chave de cache: como diferenciar variações (path, query, headers, cookies).
  • Invalidação: quando e como descartar versões antigas.
  • Controles de segurança: impedir cache de conteúdo sensível em lugar errado.

Uma Estratégia de Caching falha quando não define claramente o que pode e o que não pode ser cacheado, além de ignorar como as versões serão renovadas sem quebrar o usuário ou expor dados.


2) As camadas principais: Browser Cache, CDN e Redis

Pense em cache como uma hierarquia:

  1. Browser Cache (cliente): mais perto do usuário, custo quase zero por requisição repetida.
  2. CDN/Edge Cache: próximo geograficamente, reduz tráfego e acelera conteúdo público.
  3. Cache na aplicação (Redis/Memcached): reduz carga no banco e em serviços internos; acelera páginas e APIs dinâmicas.
  4. Cache no banco / query cache (quando aplicável): última linha; depende do SGBD.

A coordenação entre camadas é o que separa um ganho sustentável de um conjunto de “gambiarras” difíceis de operar.


3) Cache do navegador: controle fino com Cache-Control, ETag e versionamento

Quando usar

  • Assets estáticos: JS, CSS, imagens, fontes.
  • Conteúdo público com baixa criticidade: páginas institucionais.
  • Respostas de API idempotentes em alguns cenários (com muito cuidado).

Regras práticas (passo a passo)

  1. Para assets com versionamento no nome (hash)
    Exemplo: app.3a9f2c1.js
    Use cache agressivo:

    • Cache-Control: public, max-age=31536000, immutable
  2. Para HTML e conteúdo que muda com frequência
    Evite “cache eterno”:

    • Cache-Control: no-cache (permite armazenar, mas exige revalidação)
    • e utilize ETag ou Last-Modified para revalidação eficiente (304 Not Modified)
  3. Para conteúdo sensível (painéis, dados do usuário, páginas autenticadas) Em geral:

    • Cache-Control: no-store

Armadilhas comuns

  • Cachear por engano conteúdo autenticado quando a resposta varia por cookie/token.
  • Não variar por header (por exemplo, Accept-Language) e entregar idioma errado.
  • Service Worker: pode sobrepor regras e manter conteúdo “preso” no cliente. Se houver, trate o SW como parte formal da estratégia.

4) CDN: aceleração e redução de origem sem perder controle

CDNs fazem cache na borda (edge) e podem também aplicar WAF, rate limiting e mitigação de DDoS. Mas o ganho de performance vem com uma exigência: definir bem a chave de cache e a política de expiração.

Quando usar

  • Conteúdo público (assets, imagens, páginas estáticas).
  • APIs públicas ou sem personalização por usuário (ou com variações explícitas e seguras).
  • Conteúdo pesado (vídeo, downloads) com alto custo de origem.

Checklist prático para CDN

Checklist Prático para CDN
  1. Defina o que é cacheável

    • Assets: quase sempre.
    • HTML: às vezes (com TTL curto ou revalidação).
    • API: somente se não houver personalização por usuário ou se a variação estiver corretamente isolada (por exemplo, por Authorization nunca deve gerar cache público).
  2. Defina a chave de cache

    • Inclua: path e query relevantes.
    • Inclua headers necessários (ex.: Accept-Encoding, Accept-Language) via Vary.
    • Evite incluir cookies em cache público (isso fragmenta cache e pode vazar dados).
  3. Use políticas modernas

    • TTL adequado ao risco: mais curto para conteúdo dinâmico.
    • stale-while-revalidate quando suportado: entrega uma versão “não tão nova” enquanto revalida em background.
  4. Purge com critério

    • Invalidação total é cara e pode causar pico na origem.
    • Prefira purgar por prefixo/rota ou por tags (quando a CDN suporta cache tags).

Aspecto de segurança (essencial)

  • Nunca permita que respostas com Set-Cookie ou conteúdo autenticado sejam cacheadas publicamente.
  • Garanta separação por host/tenant quando há múltiplos domínios e ambientes.
  • Monitore headers de resposta (incluindo Cache-Control, Vary, Surrogate-Control) para evitar comportamento inesperado.

5) Redis como cache de aplicação: padrões confiáveis (Cache-Aside e afins)

Redis é muito usado para cache de dados e resultados de computações. A vantagem é reduzir a carga no banco e evitar recomputações. A desvantagem é introduzir consistência eventual e complexidade operacional.

Padrão mais comum: Cache-Aside (Lazy Loading)

Passo a passo:

  1. A aplicação tenta ler do Redis usando uma chave determinística.
  2. Se existir (cache hit), retorna.
  3. Se não existir (cache miss), busca no banco/serviço.
  4. Salva no Redis com TTL.
  5. Retorna a resposta.

Pontos críticos:

  • TTL: sem TTL, chaves podem acumular e nunca atualizar.
  • Serialização: padronize JSON/MessagePack/Protobuf e versões de schema.
  • Tamanho: evite valores gigantes; prefira granularidade (por item) quando fizer sentido.

Outros padrões relevantes

  • Write-through: ao escrever no banco, escreve no cache; reduz misses pós-escrita, aumenta acoplamento.
  • Write-behind: escreve no cache e persiste depois; arriscado, exige fila e garantias.
  • Read-through: biblioteca/carregador central gerencia misses; bom para consistência do acesso.

Cuidado com “cache de sessão”

Guardar sessão em Redis é comum, mas não confunda:

  • Sessão (autenticação/estado): requisitos de segurança e expiração rigorosos.
  • Cache (otimização): pode ser descartável.
    Misturar conceitos leva a incidentes quando o cache expira e “derruba” autenticação ou perde estado crítico.

6) Cache Invalidation: a parte mais difícil (e onde nascem incidentes)

Invalidação é o mecanismo que evita servir dados antigos além do aceitável. Existem três estratégias principais, que podem ser combinadas:

6.1) TTL (expiração por tempo)

  • Simples e robusto.
  • Aceita que o dado pode ficar “velho” por até TTL.
  • Bom para conteúdos com tolerância a atraso (ex.: contadores, rankings, catálogos com atualização não crítica).

Risco: inconsistência em janelas curtas e cache stampede quando muitas chaves expiram ao mesmo tempo.

Mitigações:

  • Jitter: TTL com variação aleatória (ex.: 300s ± 30s).
  • Stale-while-revalidate: servir o stale e atualizar em background.
  • Lock de recomputação: um processo recalcula, outros aguardam ou recebem stale.

6.2) Invalidação por evento (event-driven)

  • Quando um dado muda, emite evento e invalida chaves relacionadas.
  • Melhor consistência, menor janela de stale.
  • Exige bom mapeamento “dado → chaves” e uma infraestrutura de eventos (fila, stream).

Boas práticas:

  • Use cache tags (quando disponível) para invalidar grupos (ex.: “produto:123”).
  • Mantenha uma tabela de dependências ou uma convenção previsível de chaves.

Risco: eventos perdidos ou duplicados.
Mitigação: consumidores idempotentes e mecanismos de retry.

6.3) Versionamento de chaves (namespace/version key)

Em vez de apagar milhões de chaves, você muda a “versão”:

  • Chave antiga: product:123:v7
  • Nova: product:123:v8

Na prática, você armazena uma chave de versão por entidade ou por conjunto:

  • product:123:version = 8 e compõe a chave real com ela.

Vantagens:

  • Invalidação instantânea (muda a versão).
  • Evita operações caras de delete/purge em massa.

Custo:

  • Lixo residual até expirar (garanta TTL nas chaves versionadas).

7) Como escolher TTLs e políticas sem “chutar”

Uma Estratégia de Caching baseada em fatos depende de métricas. Três perguntas guiam TTL e invalidation:

  1. Qual é o impacto do dado desatualizado?
TTLs
  • Preço e estoque: impacto alto → TTL curto + evento/versão.
  • Catálogo geral: impacto médio → TTL moderado + revalidação.
  • Conteúdo institucional: impacto baixo → TTL longo.
  1. Com que frequência muda?

    • Muito frequente: cache pode perder eficiência; foque em agregações e páginas.
    • Pouco frequente: cache agressivo com invalidação por evento.
  2. Qual é o custo de recomputar?

    • Alto custo: prefira stale-while-revalidate e proteção anti-stampede.
    • Baixo custo: TTL menor e simplicidade.

8) Observabilidade e segurança: o que monitorar para não “operar no escuro”

Métricas essenciais

  • Cache hit ratio por camada (browser/CDN/Redis).
  • Latência p95/p99 antes e depois do cache.
  • Taxa de erro (especialmente timeouts na origem quando CDN falha).
  • Evictions no Redis (indica pressão de memória).
  • Top keys e distribuição de TTL.

Controles de Cyber Segurança

  • Dados sensíveis: use Cache-Control: no-store quando aplicável.
  • Separação por usuário/tenant: chaves devem incluir identificadores corretos; nunca “reaproveitar” uma resposta autenticada como se fosse pública.
  • Proteção contra cache poisoning:
    • Normalize e valide headers/query que entram na chave de cache.
    • Evite cachear respostas para requests com headers não confiáveis que alteram conteúdo.
  • Logs e auditoria: registre decisões de cache (hit/miss, TTL aplicado, variante) para investigar inconsistências.

Conclusão

Uma Estratégia de Caching eficaz combina camadas (browser, CDN e Redis), define políticas claras (TTL, revalidação, stale-while-revalidate) e trata cache invalidation como parte do design — não como correção posterior. Em termos operacionais, o objetivo é acelerar sem perder controle: garantir consistência dentro do nível de risco aceitável, evitar vazamentos de dados e reduzir o impacto de picos e falhas.

Quando a estratégia está madura, cache deixa de ser “truque de performance” e vira uma disciplina: com regras explícitas, métricas, rotinas de invalidação e segurança incorporada desde o início.

Tags: Cursos
Compartilhar este artigo: