Olá? Sou Jayon.
Hoje, gostaria de explicar os critérios para configurar o cache. Como este post está sendo escrito com base em minha experiência prática, recomendo que você o utilize apenas como referência ㅎㅎ
O que é Cache?
Cache é o armazenamento antecipado de resultados para solicitações futuras, permitindo um serviço mais rápido. Em outras palavras, é uma técnica que armazena resultados previamente e, quando uma solicitação é feita, em vez de consultar o banco de dados (DB) ou a API, acessa o cache para processar a solicitação. A origem do cache está na Lei de Pareto.
A Lei de Pareto afirma que 80% dos resultados são causados por 20% das causas. Recomendo que consulte a imagem abaixo!
Ou seja, o cache não precisa armazenar todos os resultados. Apenas armazenando os 20% mais usados durante o serviço, é possível aumentar a eficiência geral.
Quais dados devem ser armazenados em cache?
De acordo com a Lei de Pareto, nem todos os dados devem ser armazenados em cache; apenas os dados essenciais. Então, quais dados devem ser armazenados em cache?
Dados que precisam ser lidos com frequência, mas raramente escritos
Teoricamente, costuma-se dizer que "os dados que precisam ser lidos com frequência, mas raramente escritos, devem ser armazenados em cache". No entanto, os critérios para "ler com frequência" e "raramente escrever" eram bastante vagos.
Por isso, investigo os dados que serão armazenados em cache seguindo as etapas abaixo.
- Verifico o TOP 5 de histórico de chamadas de consulta RDB por meio de APM, como o DataDog.
- Entre eles, encontro as consultas de pesquisa e verifico de qual tabela elas estão sendo recuperadas.
- Verifico quantas vezes a consulta de atualização da tabela em questão está sendo chamada.
Através desse processo, verifico se a consulta é frequente, mas a consulta de atualização ocorre com pouca frequência. Na tabela que verifiquei na prática, a consulta de pesquisa foi realizada 1,74 milhão de vezes por dia, enquanto a consulta de atualização foi realizada no máximo 500 vezes. Com base nesses dados, podemos considerar essa tabela como ideal para o cache ㅎㅎ
Dados sensíveis à atualização
Dados sensíveis à atualização indicam que a discrepância entre o RDB e o cache deve ser mínima. Por exemplo, informações relacionadas a pagamentos são extremamente sensíveis à atualização, portanto, mesmo que atendam aos critérios de cache mencionados acima, é preciso considerar se a implementação é adequada.
Precisei implementar o cache em uma tabela relacionada a pagamentos que atende a essas duas características. Portanto, não apliquei o cache a toda a lógica que utiliza essa tabela relacionada a pagamentos. Em vez disso, decidi aplicar o cache parcialmente a lógicas relativamente seguras, onde pagamentos não ocorrem efetivamente.
Cache local vs. Cache global
Agora que definimos os dados e o escopo do cache, precisamos decidir onde armazená-los. Normalmente, podemos armazená-los na memória local ou em um servidor separado, como o Redis.
Cache local
O cache local é um método de armazenamento dos dados em cache na memória do servidor de aplicativo. Normalmente, o Guava cache ou o Caffeine cache são usados.
**Vantagens**
- Como o cache é consultado na memória do mesmo servidor durante a execução da lógica do aplicativo, a velocidade é rápida.
- Fácil de implementar.
**Desvantagens**
- Se houver várias instâncias, vários problemas surgirão.
Cache global
O cache global é um método que usa um servidor separado para armazenar dados em cache, como o Redis.
**Vantagens**
- Como o cache é compartilhado entre as instâncias, mesmo que o cache seja modificado em uma instância, todas as instâncias podem obter o mesmo valor de cache.
- Mesmo que uma nova instância seja criada, ela pode simplesmente visualizar o armazenamento em cache existente, então não há necessidade de carregar o cache.
**Desvantagens**
- Como o tráfego de rede é necessário, a velocidade é mais lenta em comparação com o cache local.
- Como um servidor de cache separado precisa ser usado, há custos de gerenciamento de infraestrutura.
Qual opção eu escolhi?
Atualmente, o servidor de aplicativo da empresa usa várias instâncias, mas escolhi o cache local.
Existem três razões principais para isso.
- Os dados a serem armazenados em cache no RDB são pouco menos de 40.000, e carregá-los todos na memória consome menos de 4 MB.
- O desempenho de pesquisa de dados relacionados a pagamentos precisava ser aprimorado.
- Embora o Redis já esteja em uso, armazenar um novo cache no Redis resultaria em custos de infraestrutura.
Como atualizar o cache?
Se houver vários servidores de aplicativos com cache local implementado, os valores de cache armazenados em cada servidor de aplicativo podem ser diferentes. Por exemplo, o valor de cache armazenado no servidor A pode ser "1", enquanto o valor de cache armazenado no servidor B pode ser "2" após uma modificação no servidor B. Nesse caso, se um usuário enviar uma solicitação ao balanceador de carga, ele receberá valores diferentes dos servidores A e B.
Portanto, é necessário configurar a remoção automática do cache em cada instância para que ele seja recuperado do RDB. Nesse caso, o TTL é geralmente usado.
Qual valor definir para o TTL?
TTL é a abreviação de Time To Live (Tempo de Vida) e é uma configuração que exclui o cache após um determinado tempo. Por exemplo, se o TTL for configurado para 5 segundos, os dados em cache serão excluídos automaticamente após 5 segundos. Em seguida, se ocorrer uma falha de cache, os dados serão recuperados do RDB e armazenados.
Então, qual valor definir para o TTL?
**Leitura/escrita ocorrendo em um único servidor de cache**
Se a leitura/escrita ocorrer em um único servidor de cache, como o Redis, ou em um único servidor de aplicativo com cache local, o valor do TTL pode ser aumentado para unidades de tempo ou mais. De qualquer forma, o cache será atualizado durante a gravação e o servidor que acessa o cache sempre verá os dados atualizados.
Nesse caso, em vez de configurar o TTL, o servidor de cache pode ser configurado para liberar gradualmente o cache por meio do algoritmo LRU quando ele estiver cheio.
**Leitura/escrita ocorrendo em vários servidores de cache**
Se a leitura/escrita ocorrer em vários servidores de cache, como em um servidor de cache global com vários servidores ou em vários servidores de aplicativos com cache local implementado, é melhor definir o TTL em segundos ou minutos. Isso ocorre porque existe a possibilidade de ler dados desatualizados de um servidor de cache que ainda não refletiu os dados modificados.
Nesse caso, o TTL é determinado por vários contextos. Quanto mais importante for a atualização e maior a probabilidade de alteração do valor, menor deve ser o TTL. Por outro lado, se a atualização for menos importante e a probabilidade de alteração do valor for baixa, o TTL pode ser definido por um período maior.
Como configurei o TTL?
Os dados que estou armazenando em cache estão relacionados a pagamentos e, mesmo que eu não implemente o cache em lógicas rigorosas onde os pagamentos ocorrem, a atualização ainda é importante devido à natureza dos pagamentos. No entanto, como a probabilidade de atualização é baixa, defini o TTL com segurança para 5 segundos.
Conclusão
Resumindo, o método de cache que escolhi é o seguinte.
- Dados relacionados a pagamentos
- Consultas muito frequentes, mas poucas atualizações.
- O cache é aplicado apenas à lógica onde as consultas são feitas, mas os pagamentos não ocorrem efetivamente.
- Cache local implementado, com TTL definido para 5 segundos.
A próxima etapa é realizar um teste de desempenho com base no método de cache implementado. Ainda estou pensando em como realizar o teste de desempenho especificamente, então vou escrever sobre isso em um post posterior!
Comentários0