Ao tratar de microsserviços é comum que dado uma aplicação de
disponibilidade ou desempenho seja necessário mais de uma instância
dando vida a um cluster. Junto ao ambiente clusterizado vem problemas na
implementação de cache local, já que cada uma das instâncias é um
processo independente, e a memória não é compartilhada, ocasionando que o
cache fique inconsistente entre uma instância e outra. Neste tipo de
situação a estratégia de cache local não é suficiente, pois agora quando
um dado é armazenado em cache por uma instância, a outra instância
deverá ter acesso em sua próxima consulta. Então se faz necessário a
utilização de um provedor de cache distribuído como o nosso querido Redis.
Redis é um banco de dados não relacional que armazena dados em memória, proporcionando acesso muito rapido. Ele é muito usado como cache distribuído, permitindo múltiplas conexões simultâneas. No entanto, integrar Redis diretamente no código pode gerar dependência, tornando a troca de provedor cara e trabalhosa. Para evitar esse problema, o Spring Cache oferece uma abstração que facilita o uso de cache sem amarrar o código a uma implementação específica. Ele permite armazenar, atualizar e remover dados do cache usando anotações, garantindo um gerenciamento mais simples e flexível.
Spring Cache com Redis
Para aproveitar os benefícios do Spring Cache com Redis, é necessário realizar algumas configurações, desde a adição das dependências no pom.xml
(ou outro gerenciador que você use) até a definição de beans e properties. Mas não se preocupe! Neste artigo, vamos te guiar passo a passo na configuração do Redis como cache distribuído usando as abstrações do Spring Cache. Começaremos adicionando a dependência do Spring Data Redis, depois configuraremos a aplicação para habilitar o cache e definir o Redis como provedor. Em seguida, ajustaremos a conexão, escolheremos um serializer adequado e definiremos as regras para limpeza do cache, garantindo um desempenho otimizado e seguro.
Configurando a Aplicação
Iniciaremos adicionando a dependência do Spring Data Redis
no projeto, esta dependência ira abstrair o uso do Redis na aplicação,
algumas vantagens são client e conector predefinido, serializers
personalizados para o tráfego de dados na rede, etc. Abaixo tem um
exemplo utilizando Maven
Depois de colonar a dependencia agora é definir as properties de conexão com Redis, e também
definir o redis como provedor de cache no arquivo application.properties/yaml.
Após a definição do Redis como provedor de cache é necessário que
configuramos algumas propriedades como o tempo de vida de objetos no
cache, e qual será a forma como os objetos serão serializadas. Por
padrão no Spring Data Redis é utilizado o JdkSerializationRedisSerializer
que utiliza a serialização nativa da JVM, e esta biblioteca nativa é
conhecida por permitir a execução de código remoto, que injetam bytecode
não verificado que pode causar a execução de código indesejado. Dado a
isso, a recomendação é que outros serializers sejamutilizados, como,
por exemplo, o serializer para Json da biblioteca Jackson. 
Aplicando cache nos Resultados
Com as configurações finalizadas, a aplicação está pronta para utilizar o cache de forma eficiente. Para ilustrar seu funcionamento, imagine um marketplace onde um usuário pode ter diferentes formas de pagamento para cada estabelecimento. O sistema deve permitir a consulta dessas opções de forma rápida e otimizada. Assim, na primeira vez que um usuário realizar a consulta, os resultados serão armazenados em cache, evitando consultas desnecessárias ao banco de dados nas próximas requisições. Confira a implementação no código abaixo:
Invalidando Cache
Agora o projeto já é capaz de armazenar e consultar informações no cache, mas também é essencial garantir que os dados sejam atualizados quando necessário. Para isso, precisamos definir quando o cache deve ser invalidado. Imagine que o sistema evoluiu e agora permite que os usuários adicionem novas formas de pagamento à sua conta. Sempre que isso ocorrer, o cache deve ser limpo para garantir que as próximas consultas retornem os dados mais recentes. Veja a implementação no código abaixo:
No método addPaymentMethods()
, utilizamos a anotação @CacheEvict
, que possui os mesmos argumentos da anotação @Cacheable
. Essa anotação atua como um gatilho para a invalidação do cache, garantindo que, se o método for executado com sucesso, os dados armazenados em cache sejam removidos. Caso ocorra uma exceção durante a execução, o cache permanece inalterado.
Com isso, podemos utilizar esse cache em diferentes partes do sistema, desde que as anotações e a assinatura dos métodos sejam compatíveis. Além disso, a aplicação pode rodar em múltiplas instâncias e compartilhar o mesmo cache, garantindo a consistência dos dados.
Conclusão
O uso do Spring Cache com Redis traz um grande benefício para a performance das aplicações, reduzindo a carga no banco de dados e melhorando o tempo de resposta das requisições. Ao adotar as anotações @Cacheable
e @CacheEvict
, conseguimos armazenar e invalidar dados de forma eficiente, garantindo que a aplicação mantenha informações atualizadas sem comprometer o desempenho.
Além disso, essa abordagem permite que o cache seja utilizado em diferentes partes do sistema de maneira transparente, possibilitando a escalabilidade e a consistência dos dados em ambientes distribuídos. Com as configurações corretas, o Redis se torna um aliado poderoso para otimizar aplicações Spring Boot.
Comments
Post a Comment