Hoje, estamos mergulhando no mundo do cache. O cache é uma arma secreta para a construção de sistemas escalonáveis e de alto desempenho. Existem muitos tipos de cache, mas neste artigo vamos nos concentrar no cache de objetos de back-end (cache de back-end). Dominá-lo o ajudará a construir software confiável e de alto desempenho. Neste artigo, exploraremos: Exploraremos o cache e explicaremos como ele armazena dados temporariamente para acesso mais rápido. O que é cache? : descubra como o cache aumenta a velocidade, reduz a carga do servidor, melhora a experiência do usuário e pode até reduzir custos. Benefícios do cache : nesta seção, veremos diferentes maneiras de usar o cache. Lembre-se de que cada abordagem tem prós e contras, portanto, escolha o padrão certo para suas necessidades! Padrão de cache : agora você sabe como armazenar e recuperar dados armazenados em cache. Mas como você garante que seus dados em cache permaneçam atualizados? E o que acontece quando o cache atinge sua capacidade? Prática recomendada de armazenamento em cache : embora o armazenamento em cache ofereça muitos benefícios, há momentos em que é melhor evitá-lo. A implementação do cache no sistema errado pode aumentar a complexidade e potencialmente até mesmo diminuir o desempenho. Quando não armazenar em cache O que é cache? Criar um aplicativo escalonável e de alto desempenho envolve remover gargalos e tornar o sistema mais eficiente. Os bancos de dados geralmente causam gargalos no desempenho do sistema devido aos seus requisitos de armazenamento e processamento. Isso os torna um componente caro porque precisam ser ampliados com frequência. Felizmente, existe um componente que pode ajudar a descarregar o uso de recursos do banco de dados e, ao mesmo tempo, melhorar a velocidade de recuperação de dados – esse componente é chamado . cache Cache é um armazenamento temporário projetado para gravação e leitura rápida de dados. Ele usa armazenamento de memória de baixa latência e estruturas de dados otimizadas para operações rápidas. Provavelmente você já usou Redis ou Memcached, ou pelo menos ouviu seus nomes. Estes são dois dos sistemas de cache distribuído mais populares para serviços de back-end. O Redis pode até atuar como banco de dados primário, mas isso é assunto para outro artigo! Benefícios do cache O principal benefício do cache é a sua velocidade. Ler dados de um cache é significativamente mais rápido do que recuperá-los de um banco de dados (como SQL ou Mongo). Essa velocidade vem de caches que usam estruturas de dados de dicionário (ou HashMap) para operações rápidas e armazenamento de dados em memória de alta velocidade em vez de em disco. Em segundo lugar, o cache reduz a carga no seu banco de dados. Isso permite que os aplicativos obtenham os dados necessários do cache, em vez de acessar constantemente o banco de dados. Isto diminui drasticamente o uso de recursos de hardware; em vez de procurar dados no disco, seu sistema simplesmente os acessa a partir da memória rápida. Esses benefícios melhoram diretamente a experiência do usuário e podem levar à economia de custos. Seu aplicativo responde com muito mais rapidez, criando uma experiência mais tranquila e satisfatória para os usuários. O cache reduz os custos de infraestrutura. Embora um sistema distribuído como o Redis exija recursos próprios, a economia geral costuma ser significativa. Seu aplicativo acessa dados com mais eficiência, potencialmente permitindo que você reduza seu banco de dados. No entanto, isso traz uma compensação: se o seu sistema de cache falhar, certifique-se de que seu banco de dados esteja preparado para lidar com o aumento de carga. Padrões de cache Agora que você entende o poder do cache, vamos mergulhar nas melhores maneiras de usá-lo! Nesta seção, exploraremos duas categorias essenciais de padrões: e . Esses padrões fornecem estratégias para gerenciar atualizações de cache e lidar com situações em que os dados necessários ainda não estão no cache. Cache Writing Patterns Cache Miss Patterns Padrões de escrita Os padrões de escrita determinam como seu aplicativo interage com o cache e com o banco de dados. Vejamos três estratégias comuns: , e . Cada um oferece vantagens e compensações exclusivas: Write-back Write-through Write-around Escreva de volta Como funciona: Seu aplicativo interage apenas com o cache. O cache confirma a gravação instantaneamente. Um processo em segundo plano copia os dados recém-gravados no banco de dados. Aplicativos com uso intenso de gravação, onde a velocidade é crítica e alguma inconsistência é aceitável por uma questão de desempenho. Os exemplos incluem aplicações de métricas e análises. Ideal para: Vantagens: os dados estão sempre no cache para acesso rápido, ignorando totalmente o banco de dados. Leituras mais rápidas: seu aplicativo não espera por gravações no banco de dados, resultando em tempos de resposta mais rápidos. Gravações mais rápidas: as gravações em lote reduzem a carga do banco de dados e podem potencialmente estender a vida útil do hardware do seu banco de dados. Menos esforço do banco de dados: Desvantagens: Se o cache falhar antes que os dados sejam salvos no banco de dados, as informações poderão ser perdidas. O Redis mitiga esse risco com armazenamento persistente, mas isso aumenta a complexidade. Risco de perda de dados: você precisará de um middleware para garantir que o cache e o banco de dados permaneçam sincronizados. Maior complexidade: todas as gravações vão primeiro para o cache, mesmo que os dados não sejam lidos com frequência. Isso pode levar a um alto consumo de armazenamento. Potencial para alto uso de cache: Escreva através Como funciona: Seu aplicativo grava no cache e no banco de dados simultaneamente. Para reduzir o tempo de espera, você pode gravar no cache de forma assíncrona. Isso permite que seu aplicativo sinalize gravações bem-sucedidas antes que a operação de cache seja completamente concluída. Vantagens: Assim como o Write-Back, os dados estão sempre no cache, eliminando a necessidade de leituras do banco de dados. Leituras mais rápidas: Sua aplicação só confirma uma gravação após ela ser salva no banco de dados, garantindo a persistência dos dados mesmo que ocorra uma falha imediatamente depois. Confiabilidade: Desvantagens: em comparação com o Write-Back, esta política tem alguma sobrecarga porque o aplicativo aguarda a gravação do banco de dados e do cache. As gravações assíncronas melhoram isso, mas lembre-se, sempre há o tempo de espera do banco de dados. Gravações mais lentas: todas as gravações vão para o cache, consumindo potencialmente armazenamento mesmo que os dados não sejam acessados com frequência. Alto uso de cache: Escreva por aí Com o Write-Around, seu aplicativo grava dados diretamente no banco de dados, ignorando o cache durante o processo de gravação. Para preencher o cache, ele emprega uma estratégia chamada : padrão cache-aside o aplicativo verifica o cache. Chega a solicitação de leitura: se os dados não forem encontrados no cache, o aplicativo os busca no banco de dados e os armazena no cache para uso futuro. Falta de cache: Vantagens: os dados são gravados diretamente no banco de dados, garantindo consistência. Gravações confiáveis: apenas os dados acessados com frequência são armazenados em cache, reduzindo o consumo de memória. Uso eficiente do cache: Desvantagens: se os dados não estiverem no cache, o aplicativo deverá buscá-los no banco de dados, adicionando uma viagem de ida e volta em comparação com políticas em que o cache é sempre pré-preenchido. Maior latência de leitura (em alguns casos): Padrão de falta de cache Uma falta de cache ocorre quando os dados que seu aplicativo precisa não são encontrados no cache. Aqui estão duas estratégias comuns para lidar com isso: Cache à parte O aplicativo verifica o cache. Em caso de erro, ele busca dados do banco de dados e atualiza o cache. O aplicativo é responsável por gerenciar o cache. Ponto chave: Usar um padrão Cache-Aside significa que seu aplicativo gerenciará o cache. Essa abordagem é a mais comum de usar porque é simples e não precisa de desenvolvimento em outros locais além da aplicação Leia O aplicativo faz uma solicitação sem saber do cache. Um mecanismo especializado verifica o cache e busca dados do banco de dados, se necessário. O cache é atualizado de forma transparente. Os padrões de leitura reduzem a complexidade do aplicativo, mas aumentam a complexidade da infraestrutura. Em vez disso, ajuda a descarregar os recursos do aplicativo para o middleware. No geral, o padrão write-around com cache-aside é mais comumente usado devido à sua facilidade de implementação. No entanto, recomendo incluir também o padrão write-through se você tiver algum dado que será usado imediatamente após ser armazenado em cache. Isso proporcionará um pequeno benefício no desempenho de leitura. Práticas recomendadas de cache Nesta seção, exploraremos as práticas recomendadas para usar um cache. Seguir essas práticas garantirá que seu cache mantenha dados atualizados e gerencie seu armazenamento de maneira eficaz. Invalidação de cache Imagine que você armazenou dados no cache e então o banco de dados foi atualizado. Isso faz com que os dados no cache sejam diferentes da versão do banco de dados. Chamamos esse tipo de dados de cache de "obsoletos". Sem uma técnica de invalidação de cache, os dados armazenados em cache poderão permanecer obsoletos após atualizações do banco de dados. Para manter os dados atualizados, você pode usar as seguintes técnicas: ao atualizar dados no banco de dados, atualize também a entrada de cache correspondente. Os padrões write-through e write-back lidam inerentemente com isso, mas write-around/cache-aside requer a exclusão explícita dos dados armazenados em cache. Essa estratégia evita que seu aplicativo recupere dados obsoletos. Invalidação de cache na atualização: TTL é uma política que você pode definir ao armazenar dados no cache. Com o TTL, os dados são excluídos automaticamente após um tempo especificado. Isso ajuda a limpar os dados não utilizados e fornece uma proteção contra falhas contra dados obsoletos em caso de invalidações perdidas. Time To Live (TTL): Políticas de substituição de cache Se você armazenar em cache uma grande quantidade de dados, o armazenamento em cache poderá ficar cheio. Os sistemas de cache normalmente usam memória, que geralmente é menor que o armazenamento do banco de dados primário. Quando o cache está cheio, é necessário excluir alguns dados para liberar espaço. As políticas de substituição de cache determinam quais dados remover: esta política comum remove dados que não foram usados (lidos ou gravados) há mais tempo. LRU é adequado para a maioria dos casos de uso do mundo real. Menos usados recentemente (LRU): Semelhante ao LRU, mas concentra-se na frequência de acesso. Os dados recém-gravados podem ser removidos, portanto, considere adicionar um período de aquecimento durante o qual os dados não possam ser excluídos. Menos Frequentemente Usado (LFU): Outras políticas de substituição como FIFO (First-In, First-Out), Random Replacement, etc., existem, mas são menos comuns. Quando não armazenar em cache Antes de mergulhar na implementação do cache, é importante saber quando ele pode ser a melhor opção. O cache geralmente melhora a velocidade e reduz a carga do banco de dados, mas pode não fazer sentido se: não se seu aplicativo tiver tráfego baixo e o tempo de resposta ainda for aceitável, provavelmente você ainda não precisará de cache. Adicionar um cache aumenta a complexidade, por isso é melhor implementado quando você enfrenta gargalos de desempenho ou antecipa um aumento significativo no tráfego. Tráfego baixo: o cache é mais benéfico em aplicativos com muita leitura. Isso significa que os dados do seu banco de dados são atualizados com pouca frequência ou lidos várias vezes entre as atualizações. Se o seu aplicativo tiver um grande volume de gravações, o cache poderá adicionar sobrecarga e tornar as coisas mais lentas. Seu sistema tem muita gravação: Aprendizado Neste artigo, cobrimos os fundamentos do cache e como usá-lo de maneira eficaz. Aqui está uma recapitulação dos pontos principais: certifique-se de que seu sistema tenha muita leitura e exija as ofertas de cache de redução de latência. Confirme a necessidade: selecione padrões de gravação em cache e de falta de cache que se alinhem com a forma como seu aplicativo usa os dados. Escolha os padrões com sabedoria: implemente estratégias de invalidação de cache para evitar o fornecimento de dados obsoletos. Atualização de dados: escolha uma política de substituição de cache (como LRU) para lidar com exclusões quando o cache atingir sua capacidade. Gerenciar política de substituição: Referências https://gist.github.com/jboner/2841832 https://www.bytesizedpieces.com/posts/cache-types https://www.techtarget.com/searchstorage/definition/cache https://www.youtube.com/watch?v=dGAgxozNWFE