Cacheamento
Aprenda os fundamentos de cache para reduzir a latência, diminuir a carga e melhorar o desempenho do backend em escala.
Por que o Cache Existe
O cache reduz a latência do sistema e a carga do banco de dados ao armazenar dados acessados com frequência em um armazenamento mais rápido.
- Bancos de dados são relativamente lentos e caros para consultar repetidamente.
- O cache armazena dados acessados com frequência em um armazenamento mais rápido, como a memória.
- Se os dados forem encontrados no cache, o banco de dados pode ser ignorado completamente.
Detalhes
Em sistemas de backend, muitas requisições pedem repetidamente os mesmos dados — como perfis de usuário, listas de produtos ou configurações. Consultar o banco de dados toda vez introduz latência desnecessária e aumenta a carga no sistema.
O cache resolve isso armazenando dados acessados com frequência em uma camada mais rápida, normalmente na memória. Quando uma requisição chega, o sistema primeiro verifica o cache. Se os dados já estiverem lá, ele pode retornar o resultado imediatamente sem tocar no banco de dados.
Isso melhora significativamente o tempo de resposta e reduz a pressão sobre o banco de dados, que geralmente é um dos recursos mais caros e limitados em um sistema.
Em alto nível, o cache funciona como um atalho. Em vez de recalcular ou buscar novamente os mesmos dados repetidamente, o sistema reutiliza resultados obtidos anteriormente.
Cache Hit vs Cache Miss
Cada consulta ao cache resulta em um hit (rápido) ou em um miss (requer acesso ao banco de dados).
- Um cache hit retorna os dados imediatamente do cache.
- Um cache miss exige consultar o banco de dados e depois armazenar o resultado.
- O desempenho do sistema depende muito de alcançar uma alta taxa de cache hit.
Detalhes
Quando uma requisição chega, o sistema primeiro verifica se os dados solicitados existem no cache.
Se os dados forem encontrados, isso é chamado de cache hit. A resposta é retornada rapidamente porque evita uma consulta ao banco de dados, que é muito mais lenta.
Se os dados não forem encontrados, isso é chamado de cache miss. O sistema precisa consultar o banco de dados, recuperar os dados, armazená-los no cache e então retornar a resposta.
Esse padrão cria dois caminhos distintos:
Cache → Hit → resposta rápida
Cache → Miss → banco de dados → armazenar → resposta
O objetivo do caching é maximizar os cache hits. Quanto maior a taxa de hit, mais rápido é o sistema e menor é a carga sobre o banco de dados.
Tempo de Vida (TTL)
TTL controla por quanto tempo os dados permanecem no cache antes de serem removidos automaticamente para evitar desatualização.
- TTL define a vida útil de uma entrada em cache.
- Quando o TTL expira, os dados são removidos do cache.
- Um TTL adequado equilibra a atualização dos dados com os benefícios de desempenho.
Detalhes
Os dados em cache não podem ficar para sempre porque os dados subjacentes podem mudar. Se o cache não for atualizado, o sistema pode retornar informações desatualizadas ou incorretas.
Time-To-Live (TTL) resolve isso ao associar um tempo de expiração a cada entrada em cache. Depois que a duração do TTL passa, o cache remove os dados automaticamente.
Por exemplo, um catálogo de produtos pode ser armazenado em cache por 5 minutos, enquanto uma resposta de API que muda com frequência pode ser armazenada em cache por apenas 60 segundos.
Escolher o TTL certo é uma troca. Um TTL mais longo melhora o desempenho ao aumentar os cache hits, mas corre o risco de servir dados desatualizados. Um TTL mais curto mantém os dados atualizados, mas aumenta a carga no banco de dados.
TTL é um dos mecanismos mais simples e mais usados para manter a correção do cache.
Invalidação de Cache
A invalidação de cache garante que os dados em cache permaneçam consistentes com a fonte da verdade quando os dados subjacentes mudam.
- Quando os dados mudam no banco de dados, as entradas de cache relacionadas devem ser atualizadas ou removidas.
- Uma invalidação incorreta leva à entrega de dados desatualizados ou inconsistentes.
- Estratégias comuns incluem excluir ou atualizar as entradas de cache após as alterações.
Detalhes
O cache introduz um problema fundamental: ele pode ficar desatualizado quando os dados subjacentes mudam. Se o sistema continuar servindo dados antigos do cache, os usuários podem ver informações incorretas.
A invalidação de cache resolve isso garantindo que, quando os dados são atualizados no banco de dados, as entradas de cache correspondentes sejam removidas ou atualizadas.
Uma abordagem comum é excluir a entrada de cache imediatamente após uma atualização no banco de dados. A próxima requisição resultará em um cache miss, buscará dados novos no banco de dados e armazenará o valor atualizado no cache.
Outra abordagem é atualizar proativamente o cache ao mesmo tempo que a alteração no banco de dados, mantendo ambos sincronizados.
A dificuldade está em identificar exatamente quais entradas de cache precisam ser invalidadas. Erros nesse processo são uma fonte comum de bugs em sistemas distribuídos.
Padrão Cache-Aside
O padrão cache-aside permite que a aplicação controle quando os dados são carregados para o cache.
- A aplicação primeiro verifica o cache antes de consultar o banco de dados.
- Em caso de cache miss, os dados são buscados no banco de dados e armazenados no cache.
- Essa abordagem oferece controle total sobre o comportamento de cache.
Detalhes
No padrão cache-aside, a aplicação é responsável por interagir tanto com o cache quanto com o banco de dados.
Quando uma requisição chega, a aplicação primeiro verifica se os dados existem no cache. Se existirem (cache hit), os dados são retornados imediatamente.
Se os dados não estiverem no cache (cache miss), a aplicação consulta o banco de dados, recupera o resultado, armazena-o no cache e então retorna a resposta.
Essa abordagem é amplamente usada porque é simples e flexível. A aplicação pode decidir o que armazenar em cache, quando armazenar e por quanto tempo isso deve permanecer válido.
No entanto, isso também significa que a aplicação precisa lidar com a invalidação do cache e com a consistência com cuidado, já que o cache não é mantido automaticamente em sincronia com o banco de dados.
Cache Write-Through
O cache write-through mantém o cache e o banco de dados sincronizados atualizando ambos a cada gravação.
- Cada gravação atualiza tanto o cache quanto o banco de dados.
- Isso garante que os dados em cache estejam sempre atualizados.
- A desvantagem é o aumento da latência de gravação.
Detalhes
No cache write-through, sempre que os dados são gravados, o sistema atualiza primeiro o cache e depois grava os mesmos dados no banco de dados. Isso garante que ambas as camadas sempre contenham o mesmo valor.
Como o cache é atualizado imediatamente, qualquer leitura subsequente retornará os dados mais recentes sem precisar consultar o banco de dados. Isso simplifica a lógica de leitura e evita problemas com dados desatualizados.
A desvantagem é que as operações de gravação ficam mais lentas, já que cada gravação precisa ser feita duas vezes — uma no cache e outra no banco de dados. Isso aumenta a latência e pode reduzir a taxa de processamento sob cargas intensas de gravação.
Além disso, o cache write-through pode consumir mais recursos porque ambas as camadas de armazenamento são mantidas ativamente. Mesmo assim, ele é útil em sistemas em que a consistência é crítica e é necessário um comportamento de leitura previsível.
Tecnologias de Cache
Diferentes tecnologias de cache operam em camadas diferentes para reduzir a latência e aliviar os sistemas de backend.
- Redis é um armazenamento rápido em memória com suporte a TTL e estruturas de dados avançadas.
- Memcached é um cache leve otimizado para acesso chave-valor de alta taxa de transferência.
- CDNs armazenam conteúdo em cache mais perto dos usuários para reduzir a latência global da rede.
Detalhes
O cache é implementado usando diferentes tecnologias, dependendo de onde ele fica no sistema.
Redis é um dos sistemas de cache mais amplamente usados. Ele armazena dados em memória, tornando-o extremamente rápido, e oferece suporte a recursos como TTL, listas, conjuntos e outras estruturas de dados. É comumente usado para cache em nível de aplicação, sessões e dados em tempo real.
Memcached é outro cache em memória, mas mais simples que o Redis. Ele foca exclusivamente em armazenamento rápido de chave-valor e é otimizado para alta taxa de transferência, tornando-o eficaz para casos básicos de uso de cache.
Em um nível mais alto, CDNs (Content Delivery Networks) armazenam em cache conteúdo estático, como imagens, vídeos e HTML, em servidores distribuídos pelo mundo. Isso reduz a distância que os dados precisam percorrer, melhorando o desempenho para usuários globais.
Em muitos sistemas, essas tecnologias são combinadas. Uma requisição pode primeiro atingir uma CDN, depois um cache de aplicação como o Redis, e só chegar ao banco de dados se necessário.
Onde o Cache é Usado
O cache é aplicado em várias camadas de um sistema para reduzir a latência e minimizar a carga sobre componentes mais profundos.
- O cache existe na borda (CDN), na camada da aplicação e na camada do banco de dados.
- Cada camada fornece respostas mais rápidas ao evitar solicitações desnecessárias para camadas mais profundas.
- Empilhar caches melhora o desempenho e a escalabilidade em todo o sistema.
Detalhes
O cache não se limita a um único lugar — ele é usado em várias camadas de um sistema de backend.
Na borda, CDNs armazenam conteúdo estático em cache perto dos usuários, reduzindo a latência de rede. Na camada da aplicação, ferramentas como Redis ou Memcached armazenam em cache dados acessados com frequência, como sessões de usuário ou respostas de API.
Alguns bancos de dados também incluem cache de consultas, armazenando resultados de consultas frequentes para evitar recomputação.
Essas camadas formam uma hierarquia:
Cliente → CDN → Cache da Aplicação → Banco de Dados
Cada camada absorve parte da carga de requisições, garantindo que o banco de dados só seja acessado quando necessário. Essa abordagem em camadas é fundamental para escalar sistemas de forma eficiente.
Compensações de Cache
O cache melhora significativamente o desempenho, mas introduz complexidade em torno da consistência e da correção dos dados.
- O cache reduz a latência e a carga no banco de dados, melhorando a escalabilidade do sistema.
- Ele introduz riscos como dados desatualizados e problemas de consistência.
- Gerenciar a invalidação do cache se torna um desafio importante no design de sistemas.
Detalhes
O cache é uma das formas mais eficazes de melhorar o desempenho do sistema. Ao servir dados de um armazenamento mais rápido, os sistemas podem responder com mais rapidez e lidar com muito mais tráfego com menos carga no banco de dados.
No entanto, esse ganho de desempenho vem com compensações. O maior problema é o dado desatualizado — os valores em cache podem não refletir mais o estado mais recente do banco de dados.
Garantir a consistência entre o cache e o banco de dados introduz complexidade adicional. Os desenvolvedores precisam projetar cuidadosamente estratégias de invalidação para manter os dados corretos.
Na prática, o cache é um equilíbrio. Os sistemas trocam certo nível de consistência e complexidade por grandes melhorias em velocidade e escalabilidade.
Seção de Perguntas
1 / 5
Esta lição faz parte do conteúdo premium
Faça upgrade para o plano premium para remover o desfoque e liberar a leitura completa.