Padrão Cache-aside
Hi guys 👋
Pessoal, neste post vamos falar um pouco sobre o padrão Cache-Aside e como estou utilizando essa estratégia no meu projeto.
O que é o padrão Cache-Aside?
Cache-Aside é uma estratégia de cache onde armazenamos o resultado de uma consulta que é custosa para a aplicação. Dessa forma, após o valor estar salvo em cache, não é necessário realizar novamente a consulta no banco de dados ou em uma API externa.
O resultado disso é:
. ⏱️ Menor tempo de resposta
. 💰 Redução do custo de processamento
. 📉 Menor carga sobre serviços externos e banco de dados
Posso usar cache em tudo?
Não exatamente.
Cache é uma excelente solução para melhorar a performance da aplicação, mas não é bala de prata. Por isso, deve ser utilizada com parcimônia e sabedoria, avaliando bem o contexto e os dados envolvidos.
Onde não devo usar cache?
O padrão Cache-Aside tem como objetivo manter em cache, por um determinado tempo o resultado de consultas ao banco de dados ou a serviços externos, evitando chamadas repetidas enquanto o valor ainda for válido.
Porém, não faz sentido usar cache quando precisamos garantir a integridade do dado em tempo real, como por exemplo:
.💰 Saldo de conta bancária
.📦 Estoque de produtos
.💲 Preço de um item
.📈 Cotação de criptomoedas
Esses valores podem mudar com muita frequência e precisam ser recuperados no exato momento da consulta.
Embora existam estratégias de invalidação de cache, se o custo de implementar e manter esse controle for maior do que o custo da consulta original (seja em complexidade ou processamento), na minha opinião não compensa armazenar esse tipo de dado em cache.
Cache-Aside na prática: como implementei no meu projeto
Depois de todos os disclaimers, vamos para a parte prática 😊
Vou mostrar como apliquei cache na minha aplicação Redesenhe e onde vejo necessidade de uso no sistema atualmente.
⚙️ Passos da implementação:
-
Adicionei a dependência do Redis no pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <exclusions> <exclusion> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency> -
Criei um arquivo de configuração Responsável por criar os Beans necessários para o Redis
@Configuration public class RedisConfig { @Value("${spring.redis.host}") private String host; @Value("${spring.redis.port}") private Integer port; @Bean public JedisConnectionFactory jedisConnectionFactory() { RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(host, port); return new JedisConnectionFactory(config); } @Bean public RedisCacheConfiguration cacheConfiguration(ObjectMapper mapper) { ObjectMapper mapperCopy = mapper.copy() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .activateDefaultTyping( new ObjectMapper().getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.EVERYTHING, JsonTypeInfo.As.PROPERTY ); return RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofMinutes(10)) .serializeValuesWith( RedisSerializationContext.SerializationPair.fromSerializer( new GenericJackson2JsonRedisSerializer(mapperCopy) ) ); } } -
Defina as credenciais de conexao
redis: ssl: false host: localhost port: 6379 timeout: 10000 -
Criei uma camada de persistência Para separar a lógica de armazenamento e recuperação do cache
@Component public class RedisPersiste { @Autowired private StringRedisTemplate redisTemplate; public String obter(final String key) { return redisTemplate.opsForValue().get(key); } public void save(final String key, final String value, final Long ttl) { redisTemplate.opsForValue().set(key, value, ttl, TimeUnit.MINUTES); } public void delete(final String key) { redisTemplate.delete(key); } } -
Implementei a lógica de leitura e escrita no cache Quando o valor não existe no cache, busco na fonte original e salvo

-
Teste de performance (sem cache) Tempo de resposta da API quando não há registro em cache

-
Teste de performance (com cache) Tempo de resposta da mesma API com o valor já em cache

Quer se aprofundar mais?
Se você quiser entender melhor o padrão Cache-Aside, recomendo fortemente este vídeo incrível do Renato Augusto:
Pessoal, por hoje é isso! Espero que esse conteúdo tenha despertado seu interesse em aprender mais sobre cache e arquitetura de software.
Até o próximo post 👋
Carregando comentários...
