Spring + Redis: Como melhorar sua aplicação com caching


 

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

Popular posts from this blog

Spring VS Micronaut VS Quarkus

Java + Kafka, Como essa parceria fucniona ?