DesenvolvimentoUso otimizado de cache para performance de aplicações WEB

Uso otimizado de cache para performance de aplicações WEB

-

Uso otimizado de cache para performance de aplicações WEBNo final de 2009, fui convidado para formar um novo time de desenvolvimento que ficaria responsável pela versão 2010 do CartolaFC, um Fantasy Game do SporTV. O maior desafio deste novo time não seria o tempo, embora este também seria decisivo, e sim a tecnologia. Não havia ainda na globo.com um projeto com o requisito de ser 100% dinâmico e com a performance exigida. Diversas questões técnicas levaram a um desempenho extraordinário desta nova versão. Porém, acredito que a nossa decisão mais acertada tenha sido a de reescrever do zero a aplicação e redesenhar completamente sua arquitetura para uma melhor utilização do cache em memória e aumento da performance.

Naturalmente, os desenvolvedores fazem o cache das respostas às consultas aos recursos externos (banco de dados, APIs etc). Dependendo das regras de negócio da aplicação, isso pode até fazer sentido. Consultas simples a objetos sem relacionamento com outros ou que sofram pouca atualização entram nesse universo. Porém, quando temos consultas mais complexas e que são mapeadas em diversos objetos, esse pattern deve ser evitado por dois motivos principais: otimização do uso da memória ocupada pelo cache e performance na expiração ou regeração do conteúdo.

Cenário

Quando um usuário do CartolaFC visualiza a escalação do seu time, diversos jogadores são exibidos. Na abordagem tradicional, faríamos uma query que obteria todos os jogadores escalados, o status de cada jogador (lesionado, suspenso etc) e seu valor (em cartoletas). O resultado desta query seria guardado no cache para um acesso futuro. Quando um segundo usuário acessar sua escalação, este mesmo processo ocorrerá e uma nova entrada de cache será gerada. Parece razoável, não? E se os dois usuários possuírem a mesma escalação? Extrapole esse processo para toda a base de usuários do jogo e o desastre será iminente.

Solução de Cache

Na nossa abordagem, a query obtém e faz o caching apenas da lista com os IDs dos jogadores. Para cada ID, há um objeto <jogador> correspondente armazenado no cache. Assim, o cache de objetos do tipo <jogador> ocupará um espaço fixo na memória e, se aplicamos essa mesma regra a todos os possíveis objetos do Cartola (jogadores, usuários, ligas etc). E mais: o tamanho do cache só aumentará quando um novo usuário entrar no jogo, já que teremos novas listas de jogadores escalados, amigos e ligas. Dessa forma, chegamos ao primeiro (e principal) benefício desta abordagem: uso otimizado de memória.

Este processo também aumenta a performance da aplicação ao efetuar o expurgo e regeração das entradas de cache de forma mais restritiva. Quando, por exemplo, o valor de um atleta é alterado após o fechamento da rodada, na abordagem tradicional deveríamos expirar o cache de cada um dos milhões de times escalados. Na nova abordagem, apenas o cache do objeto <jogador> será expurgado e todas as escalações, que são apenas referências para este objeto, serão atualizadas. Uma lista de IDs só será expurgada quando um novo objeto for criado ou apagado do sistema.

Discutidas as vantagens da arquitetura otimizada de cache, preciso revelar algumas desvantagens (ou, talvez, apenas boas práticas). A primeira: o desenvolvedor deve ter muito cuidado ao escrever o código. A programação orientada a cache possui um paradigma bastante diferente da “sem cache”. Para ilustrar essa afirmação, imagine uma aplicação sem cache e pense no código que você faria para obter todos os jogadores cadastrados no CartolaFC. Pense, então, no código para obter apenas os jogadores lesionados. Muito provavelmente, no primeiro caso seria algo como “select * from jogadores” e, no segundo, algo como “select * from jogadores where <sua cláusula aqui>. Em uma abordagem com caching, como a descrita neste artigo e utilizada no CartolaFC, a resposta seria realizar um loop for sobre a lista de IDs obtidas com o select sobre toda a base de dados e, para cada ID, verificaríamos o status do <jogador> correspondente. Ou seja, um filtro aplicado nos elementos do cache e não do banco de dados.

A segunda desvantagem é o aumento da complexidade do código uma vez que o controle de expurgo dos objetos deve ser feito pelo desenvolvedor. No CartolaFC, desenvolvemos um middleware baseado nos decorators do Python em que o código @cached sinaliza que a resposta daquele método deve ser criada no cache. Esse middleware também foi utilizado para estender os métodos CRUD da ORM e, a cada ação realizada, uma operação era realizada no cache.

Uma última dica: dê preferência a um sistema de caching distribuído, como o memcached ou o redis. Isso evita que a replicação do cache em cada instância da sua aplicação. Deixe que suas APIs se preocupem em encontrar a chave desejada. E, muito importante, escolha uma ORM que lhe ajude nessa arquitetura.

[Crédito da imagem: Performance – ShutterStock]

Victor Pantojahttp://victorpantoja.com
Engenheiro eletrônico e de computação pela UFRJ e mestre em informática pela PUC-Rio, atuo desde 2005 como engenheiro de software na globo.com tendo desenvolvido aplicações web de alta performance e escaláveis como o globoesporte.com e também o fanstasy game Cartola FC.

Latest news

4 bons conceitos para apoiar a sua identidade de marca

No mercado, existem marcas que, ao falar seus nomes, rapidamente associamos com determinadas palavras que são boas para quem...

Estratégia de comunicação B2B para redes sociais: dos posts para as vendas!

Adaptar seu conteúdo permite experimentar diferentes maneiras de mostrar sua empresa de TI, os benefícios dos seus serviços e não ser tão repetitivo com algumas táticas.

IA para MSPs: como a inteligência artificial está transformando o mercado de serviços gerenciados

A Inteligência Artificial (IA) está desempenhando um papel crucial na transformação dos Prestadores de Serviços Gerenciados (MSPs). Mais do...

O que é integração de sistemas de RH e como ela facilita o trabalho?

A integração de sistemas de RH traz muitos benefícios, principalmente em termos de otimização do tempo e de recursos. Sem ela, diferentes plataformas podem gerar dados desconexos e difíceis de consolidar, o que pode levar a erros e à sobrecarga de trabalho manual.
Publicidade

Cibersegurança como pilar da resiliência empresarial: a abordagem estratégica dos MSPs

Na última década, a segurança cibernética deixou de ser um tema restrito às áreas de TI para se tornar...

ADDEE traz HaloPSA ao Brasil, apostando na eficiência para MSPs

Plataforma de atendimento e automação promete otimizar a gestão de serviços com funcionalidades integradas para todo o ciclo de vida...

Must read

4 bons conceitos para apoiar a sua identidade de marca

No mercado, existem marcas que, ao falar seus nomes,...

Estratégia de comunicação B2B para redes sociais: dos posts para as vendas!

Adaptar seu conteúdo permite experimentar diferentes maneiras de mostrar sua empresa de TI, os benefícios dos seus serviços e não ser tão repetitivo com algumas táticas.
- Advertisement -

You might also likeRELATED
Recommended to you