DBAtlas · Atlas de operações de banco de dados

Decisão: qual estratégia de cache?

Um cache mantém os dados lidos com frequência em uma camada rápida à frente do banco (ex.: Redis), reduzindo a latência e a carga do banco. Mas nem todos os dados são adequados para cache, e uma invalidação errada cria risco de dados defasados/incorretos. Esta árvore primeiro verifica se você realmente precisa de cache e depois ajuda a escolher entre cache-aside, read-through, write-through e write-behind com base no padrão de leitura/gravação, além de tratar da prevenção de stampedes.

Como é a sua carga: predominam leituras ou gravações?

Um cache compensa mais quando os mesmos dados são lidos muitas vezes (muitas leituras) e não mudam com frequência. Primeiro, estabeleça o padrão geral: os dados são muito lidos e raramente alterados, são atualizados constantemente, ou você não tem certeza se vale a pena adicionar um cache?

  • Muitíssimas leituras, os dados mudam relativamente pouco
  • As gravações também são intensas; os dados gravados são lidos imediatamente/com frequência
  • Não tenho certeza; eu realmente preciso de cache?

Quem deve ser responsável por popular o cache?

Em um cenário com muitas leituras, a escolha-chave é quem popula o cache. Sua aplicação deve gerenciar o cache explicitamente e recorrer ela mesma ao banco (alta flexibilidade), ou a camada de cache deve buscar os dados no banco subjacente em caso de miss e retorná-los de forma transparente?

  • Deixar a aplicação gerenciar explicitamente; quero flexibilidade e controle
  • Deixar a camada de cache buscar no banco em caso de miss (transparente)

Nas gravações, a prioridade é a consistência ou a velocidade de gravação?

Se as gravações forem intensas, você precisa decidir quão consistentes os dados gravados serão entre o cache e o banco. O cache e o banco devem ser atualizados juntos a cada gravação para garantir consistência (gravações um pouco mais lentas), ou as gravações devem ir primeiro ao cache e ser aplicadas ao banco de forma assíncrona em segundo plano (gravações muito rápidas, mas com risco de perda)?

  • A consistência importa; as leituras devem estar sempre atualizadas
  • A velocidade de gravação é crítica; consistência levemente atrasada e risco de perda são aceitáveis

Recomendação: não adicione cache por enquanto

Um cache não é gratuito: introduz um problema de consistência (dados defasados), infraestrutura extra e complexidade de invalidação. Se a consulta já for rápida ou os dados mudarem a cada request, um cache não acrescenta benefício, apenas superfície de falha.

Recomendação: cache-aside (lazy loading)

Com cache-aside, a aplicação verifica primeiro o cache; se o dado não estiver lá (miss), lê do banco, grava no cache e o retorna. É o padrão mais comum e flexível; o cache é preenchido apenas com dados realmente solicitados.

Recomendação: cache read-through

Com read-through, a aplicação conversa apenas com o cache; em caso de miss, a própria camada de cache busca os dados no banco e os popula (por meio de um provider/loader). O código da aplicação fica mais simples e a lógica de preenchimento fica em um só lugar.

Recomendação: cache write-through

Com write-through, toda gravação vai tanto para o cache quanto para o banco (de forma síncrona); ambos são atualizados juntos. Assim, o cache nunca fica atrás do banco e as leituras sempre veem dados atualizados.

Recomendação: cache write-behind (write-back)

Com write-behind, a gravação vai primeiro ao cache e retorna imediatamente ao usuário; a gravação no banco acontece em segundo plano, de forma assíncrona (em lotes/com atraso). A velocidade de gravação é a maior, mas traz riscos de durabilidade e consistência.

Abrir no DBAtlas →