Introdução ao nosso amigo cache.

Carly Christian
3 min readMay 20, 2020

--

Fala galera, eu de volta aqui. Hoje vou começar a falar sobre cache, mas este é o primeiro artigo de dois que irei lançar para falar deste tema. Vamos ver aqui o start do tema e a aplicação local utilizando spring boot, entender as anotações básicas e seu conceito. Em um segundo artigo vamos falar de cache distrubuído e sua aplicabilidade, além de configurações relevantes do cache. Agora, bora falar de cache.

O que é e qual a finalidade do cache na prática para APIs ?

Eu defino cache como: Uma técnica de memorização inteligente de alocação e recuperação de dados.

O que é isso ? De forma simples, os dados de consultas custosas são armzenados de forma que possam ser recuperados com um custo menor que o de suas consultas originais.

Qual a finalidade disso ? Garantir uma melhor performance, que em muitos cenários é um gargalo nas aplicações.

Você pode utilizar cache local ou distribuido (com redis por exemplo, vou falar sobre isso no próximo artigo), ambos são úteis e tem suas finalidades e aplicações para cada cenário e arquitetura adotada. Agora vou apresentar o uso de cache local com spring boot de forma simples e disponibilizo aqui um projeto exemplo que pode te ajudar a entender melhor.

O spring boot prove um conjunto de recursos para implementar cache. Para começar precisamos anotar a aplicação habilitando o cache.

@SpringBootApplication

@EnableCaching

public class CachectmaitApplication {

public static void main(String[] args) {

SpringApplication.run(CachectmaitApplication.class, args);

}

}

Agora vamos ver as anotações que podemos usar para cachear o que faz sentido na aplicação e como atualizar e remover este cache com as anotações.

@Cacheable

Essa anotação cria o cache e podemos atribuir a ele nome e chave, como podemos ver abaixo:

@SneakyThrows

@Cacheable(cacheNames = “Pessoas”, key = “#root.method.name” )

public List<PessoaResponseDTO> getAll(){

Thread.sleep(2000L);

return pessoaRepository.findAll()

.stream()

.map(pessoaResponseConverter::convert)

.collect(Collectors.toList());

}

Após isso, quando chamar getAll será acionado o repositório, depois as próximas requisições o cache será acionado, até que o cache seja inválido por alguma configuração (vamos falar mais sobre isso no próximo artigo mas nesse ainda falaremos um pouco mais a frente). Após a primeira requisição será alocado um espaço em memória, o identificador “Pessoas::getAll” (configuração cacheNames + key) para armazenar todos os registros retornados na consulta. Podemos consultar por chave única, assim configuramos o cache para armazenar esses registros. A configuração é a mesma mudando que a chave do cache é dinâmica, ou seja, para cada identificador da Pessoa será criado/alocado os dados, veja abaixo:

@SneakyThrows

@Cacheable(cacheNames = “Pessoa”, key = “#uuid” )

public PessoaResponseDTO getPessoaByUuid(final String uuid) {

Thread.sleep(2000L);

return pessoaResponseConverter.convert(getByUuid(uuid));

}

@CachePut e @CacheEvict

Os dados foram armazenados em cache, mas os dados são mutáveis, então precisamos atualizar ou descartar essas dados em cache, para que assim a aplicação possa recuperar os novos dados e atualizar/rearmazenar. É importante frizar que esta etapa é fundamental para que o cache não produza falsos dados reais, por isso mapear devidamente é muito importante. Abaixo vemos o exemplo:

@CachePut(cacheNames = “Pessoa”, key=”#request.getUuid()”)

@CacheEvict(cacheNames = “Pessoas”, allEntries = true)

public PessoaResponseDTO put(final PessoaRequestPutDTO request) {

return pessoaRepository.getByUuid(request.getUuid())

.map(pessoa -> pessoaRequestConverter.convert(request, pessoa))

.map(pessoaRepository::save)

.map(pessoaResponseConverter::convert)

.orElseThrow(this::generateNotFound);

}

Como o nome já sugere, o @Cacheput atualiza o cache. (Obs: Poucas pessoas falam isso, mas saiba que caso você atualize um dado que não está em cache, ele irá criar o cache do dado atualizado.) Já o @CacheEvict remove o cache armazenado e caso não exista não se preocupe que isso é tratado internamente.

Existem muitos detalhes relevantes e propriedades importantes das anatoções que fazem do trabalho com cache algo delicado e que pode dar muitas dores de cabeças. Para ver um pouco mais na prática sugiro baixar o projeto exemplo e dar uma olhada. Além disso, em breve lanço o segundo artigo desta série falando de cache distribuído com spring boot e redis, nele vou abordar as configurações básicas e importantes para sua aplicação. Pode adquirir mais referências aqui.

Antes de ir mais uma coisinha: Nunca se esqueça que cache é bom mas a diferença entre veneno e antídoto é a dose.

É isso e nos falamos em breve no segundo artigo da série. vlw flw ! :D

Originally published at https://www.linkedin.com.

--

--

Carly Christian
Carly Christian

Written by Carly Christian

Oi, eu sou o carly. Gosto de falar sobre varios assuntos e visões que tenho sobre o mundo, é isto.

No responses yet