trilha

System Design/02 - Componentes/Caching2 min

Cache-Aside

Perguntas-guia
  • Que problema isso resolve?
  • Quando usar / quando NÃO usar?
  • Qual o principal trade-off?
  • Como isso falha em produção?

Conceito

Também chamado lazy loading. A aplicação gerencia o cache explicitamente: consulta primeiro, e só busca na fonte quando erra.

ler(chave):
    valor = cache.get(chave)
    se valor existe:  return valor          # HIT
    valor = banco.get(chave)                # MISS
    cache.set(chave, valor, ttl)
    return valor

Na escrita, o padrão usual é escrever no banco e invalidar o cache — não atualizar o cache:

escrever(chave, valor):
    banco.set(chave, valor)
    cache.delete(chave)      # invalida, não atualiza

Invalidar em vez de atualizar evita uma corrida clássica: duas escritas concorrentes podem gravar no cache em ordem inversa à do banco, deixando o cache permanentemente errado.

Trade-offs

Ganha Perde
Só cacheia o que é realmente pedido Todo primeiro acesso é lento
Resiliente: cache fora do ar ≠ sistema fora Dado pode ficar obsoleto (janela de TTL)
Simples de entender e implementar Três idas na primeira leitura

É o padrão mais usado justamente pelo equilíbrio: memória proporcional ao uso real, e falha do cache degrada performance sem derrubar o sistema.

Os problemas conhecidos:

  • Cache stampede — chave popular expira e N requisições vão ao banco juntas. Defesas: lock, jitter no TTL, Refresh Ahead.
  • Cache penetration — pedidos por chaves que não existem nunca populam o cache e sempre batem no banco. Defesa: cachear o "não existe" com TTL curto, ou um Bloom filter.
  • Janela de inconsistência — entre a escrita no banco e a invalidação, uma leitura concorrente pode repopular o cache com o valor velho.

Exemplo prático

Catálogo de produtos com 100 mil itens, dos quais ~2 mil concentram o tráfego.

Com cache-aside, a memória usada tende a esses 2 mil — o cache se molda ao padrão real de acesso, sem ninguém precisar prever quais são os populares. Com Write-through, os 100 mil ocupariam espaço, incluindo os que ninguém consulta.

O custo aparece no primeiro acesso a cada produto (~50 ms em vez de ~1 ms) e num detalhe operacional: depois de limpar o cache ou reiniciar o cluster, todo o tráfego cai no banco de uma vez. Reaquecer o cache antes de liberar tráfego é parte do procedimento.

Relacionado


Parte de Caching · roadmap.sh/system-design

Buscar

Busca por título, seção e texto das notas