Sharing is caring!

Talvez já tenha acontecido com você: ao acessar uma página para preencher um formulário, você acaba desistindo de completá-lo até o final. Preencher diversos campos em um único formulário web é algo um pouco tedioso, mas pior do que sofrer com o tédio, é faltar paciência ao tentar carregar um campo como a lista de cidades ou de bairros. Esse é um bom exemplo da possibilidade do uso de cache em uma aplicação web.

Com tantas opções para adicionar cache na sua aplicação, qual é a ideal? Redis, Memcached, Hazelcast, Guava Cache ou um simples java.util.Map? É uma resposta difícil de ser respondida, mas o que considero importante é utilizar uma das soluções.

Aqui na Wavy usamos o Redis e Hazelcast, mas temos outras soluções de cache também. (Compartilho um excelente post do Rodolfo Bitu sobre o Redis, que vale a pena conferir aqui).

Senta que lá vem a história…

Para explicar o Hazelcast, gosto de contar uma história sobre o seu uso em uma das nossas aplicações, vamo aos detalhes:

O Apolo é um dos nossos sistemas que possibilita que os parceiros assinem usuários nos nossos produtos. A primeira versão só contava com um servidor. No fluxo de assinatura, ao receber uma requisição, algumas informações extras eram recuperadas no nosso banco de dados antes de seguir com a assinatura.

01Representação da v1 do Apolo.

Para a primeira versão, tudo funcionava tranquilamente, mesmo acessando o banco de dados a cada requisição. A quantidade de requisições era baixa, portanto a solução estava atendendo perfeitamente.

Pensando na solução, vimos a possibilidade de melhorar essa arquitetura, principalmente depois do aumento da quantidade de requisições.

Uma nova proposta foi criada, agora adicionamos uma solução simples de cache, um java.util.Map, onde eram armazenados alguns dados nesse Map para evitar o acesso ao banco de dados.

02.pngApolo na v2 – Inclusão do cache.

Até esse momento tudo funcionava lindo! O tempo de resposta melhorou e encontramos uma solução para lidar com a grande quantidade de requisições, só que não! As requisições foram aumentando e na Wavy sempre temos um servidor como backup, para ter segurança caso um deles apresente problema.

03Apolo na v3 – Com dois servidores e solução cache parcial

Problema resolvido? Não, justamente por causa da solução de cache. Se uma requisição fosse para o primeiro servidor, os dados de cache seriam armazenados somente para o primeiro servidor. Caso uma outra requisição com os mesmos params fosse para o segundo server, ele precisaria novamente ir ao banco de dados e armazenar no cache separado.

Um outro problema seria com relação ao tempo de vida dos dados na solução de cache, como seriam expirados? Somente quando o servidor fosse reiniciado? Criar um endpoint para limpar todos os dados do cache?

Foi nesse cenário que entrou o Hazelcast

04Versão final do Apolo – Hazelcast.

O Hazelcast é uma solução de cache distribuído de código aberto baseada em Java. No caso do Apolo funcionou muito bem, pois ele roda embarcado na aplicação e possibilita a criação de um cluster entre os diversos servidores, ou seja, o cache armazenado pelo servidor1 será compartilhado com qualquer um dos servidores do Apolo nas próximas requisições.

Um outro detalhe: se um dos servidores reiniciar por alguma manutenção, ao retornar, ele é adicionado automaticamente ao cluster e passará a utilizar também os dados de cache já armazenados pelos outros servidores.

Mais detalhes do Hazelcast

Dentre as diversas configurações possíveis no Hazelcast, para mim, as que mais se destacam são:

  • Possibilidade de criar configurações específicas para cada grupo de informações que serão armazenadas no cache (MapConfig)
  • Tamanho máximo de registros no cache (max-size)
  • Política de exclusão de registros (eviction-policy)
    • LRU: Least Recently Used – Menos recentemente usado
    • LFU: Least Frequently Used – Menos frequentemente usado
    • NONE: Ignora a configuração de tamanho máximo
  • Tempo de vida (time-to-live-seconds) de cada elemento dentro do cache
  • Tempo máximo esperando (max-idle-seconds)

Com esses ajustes finos é possível definir regras para cada estrutura de um MapConfig.

Como o Hazelcast funciona embarcado na aplicação, não é necessário um segundo servidor ou iniciar um outro serviço. Ao subir a aplicação, o Hazelcast estará pronto e ativo para armazenar os dados em cache.

Outras soluções de cache como o Redis ou Memcached, um novo serviço precisará ser iniciado no mesmo servidor da sua aplicação ou em algum outro servidor, além disso, a aplicação precisará controlar caso fique indisponível o acesso ao Redis ou Memcached.     

Considerações finais

O uso de cache em aplicações permite um melhor tempo nas respostas das requisições que envolvem acesso ao banco de dados. Um outro ponto que vale destacar, é que não existe solução perfeita, Hazelcast, Redis, Memcached, todos têm suas características e o ideal é você saber qual deles atenderá da melhor forma a necessidade da sua aplicação.

Mostramos como foi possível melhorar a performance da resposta do Apolo com o uso de uma solução de cache, o Hazelcast. Além de um melhor tempo, com ele foi possível manter em todos os servidores os mesmos dados de cache formando um cluster. Um segundo ponto é o gerenciamento de cada item armazenado no cache, com configurações distintas para cada grupo de informações armazenadas (MapConfig).

Referências

 

Posted by:Esdras Barreto

Deixe seu comentário