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

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

-

Publicidade

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

Software para MSPs: indo além do preço ao procurar pelas ferramentas certas

Confira 5 dicas essenciais para escolher as melhores plataformas para compor o monitoramento e segurança da infraestrutura de TI dos seus clientes

Rápido, seguro e nativo: Chrome chega ao Windows no Snapdragon

"Projetamos o navegador Chrome para ser rápido, seguro e fácil de usar em desktops e dispositivos móveis, e estamos sempre procurando maneiras de levar essa experiência a mais pessoas", disse Hiroshi Lockheimer, Senior Vice President, Google.

Convergir segurança física e TI garante maior proteção para instalações, redes e negócios

Hoje, com o aumento das violações de dados em todo o mundo e as regulamentações de privacidade evoluindo rapidamente, é mais importante do que nunca que segurança física e TI trabalhem juntas para proteger instalações e infraestrutura de rede.

Evoluindo de modelos LLM para modelos LAM

Os modelos LAMs marcam um avanço fundamental na inteligência artificial, transcendendo as capacidades convencionais de geração de texto dos LLMs. Ao contrário dos LLMs que respondem com texto, os LAMs captam a intenção por trás da linguagem humana, decifrando objetivos complexos. Eles então traduzem esses objetivos em ações do mundo real, como por exemplo, filtrar e-mails com base em suas tarefas agendadas.
Publicidade

O impacto da IA generativa nas memórias RAM e SSDs: Um olhar sobre o futuro do hardware

Algoritmos de IA otimizados podem reduzir o uso de RAM ao aplicar técnicas como computação distribuída e processamento eficiente de dados, garantindo uma melhor utilização da memória disponível. Da mesma forma, um uso eficiente dos SSDs pode minimizar o impacto das operações de entrada/saída (I/O) no desempenho.

5 Insights sobre Gestão da Experiência

Empresas de referência em Gestão da Experiência crescem 190% mais que a média do seu segmento. É o que aponta o Relatório do Boston Consulting Group (BCG). E os resultados positivos não param por aí: o retorno de investimento pode ser até 55% maior para acionistas das empresas em um prazo de cinco anos e o NPS chega a aumentar cerca de 70%.

Must read

Software para MSPs: indo além do preço ao procurar pelas ferramentas certas

Confira 5 dicas essenciais para escolher as melhores plataformas para compor o monitoramento e segurança da infraestrutura de TI dos seus clientes

Rápido, seguro e nativo: Chrome chega ao Windows no Snapdragon

"Projetamos o navegador Chrome para ser rápido, seguro e fácil de usar em desktops e dispositivos móveis, e estamos sempre procurando maneiras de levar essa experiência a mais pessoas", disse Hiroshi Lockheimer, Senior Vice President, Google.
- Advertisement -

You might also likeRELATED
Recommended to you