Nessa série de posts estamos furando a bolha, saindo do desenho básico de 3 camadas, indo além. Hora vamos abordar práticas, hora vamos abordar ferramentas.
Hoje vamos falar de uma prática: Reduzir a pressão sobre aplicação e banco de dados.
Essa é uma prática super comum, mas negligenciada principalmente no período em que você está transitando entre um desenho hyper-conectado ao banco para um desenho mais desacoplado.
No mundo real nós usamos técnicas e mais técnicas para reduzir a “pressão” ou o consumo sobre pessoas, ou seja, reduzir o consumo de tempo de indivíduos. Eu, você, seu pai, sua mãe, todos em algum momento fizemos isso, mesmo que de forma intuitiva.
Nesse exato momento eu escrevo esse post de forma a poder compartilhar o link dessa página com milhares de pessoas ao invés de dizer a mesma coisa milhares de vezes.
Essa é uma forma de reduzir a pressão sobre mim, deixando o post em um lugar (cache) onde você pode acessar a qualquer momento, mesmo que eu esteja dormindo, viajando, assistindo netflix ou mesmo esteja adoentado e distante da internet. Assim eu consigo otimizar meu tempo e parar de responder as mesmas coisas muitas vezes.
Um SAC faz isso muito bem com um FAQ.
Até quando as pessoas burlam o FAQ e tentam usar o call center, vêm os chatbots que incorporam o FAQ e passam a responder com o FAQ em outro canal.
Nós estamos falando de algo precioso e escasso: Tempo de pessoas. E estamos trocando esse tempo alocado por um recurso mais barato, pura computação.
Os sistemas desenvolvidos apenas com 3 camadas (isso quer dizer, somente elas e nada, absolutamente nada mais), são sistemas hyper-conectados, onde 100% das páginas ou API’s demandam consultas ou escritas em banco para que sejam entregues, a todo momento, diversas vezes, por diversos motivos. Isso quer dizer que mesmo que o dado não tenha mudado, seu sistema precisa ir ao banco de dados consultar algumas estruturas de dados, trazer a resposta e compor uma tela, sempre, a todo momento.
Isso parece certo porque é o que aprendemos nos primeiros dias ou até anos. Talvez, se você ficou preso ao mesmo tipo de projeto a vida toda, é possível e talvez provável que só conheça essa realidade.
3 principais medidas estão no coração de sistemas eficientes que precisam de escala e aguentam cargas de trabalho maiores:
1 – Reduzir os acessos ao banco.
2 – Reduzir os acessos à aplicação.
3 – Reduzir os acessos ao Web Server.
Nós vamos entender esses 3 aspectos hoje!
Resetando entendimentos errados sobre cache
A primeira medida é entender qual o tempo de vida do cache para cada item.
E mesmo que o pessoal de negócio diga que não deve ter cache, ignore! Na prática estamos falando de um cache com tempo de vida menor, mas nunca sem cache.
Não é equipe de negócio que determina se deve ter cache ou não.
Equipe de negócio dá o insumo para sabermos se teremos um cache com maior ou menor TTL, mas não é competência deles decidir se há cache ou não.
Antes que você diga que “tem coisas que não dá para ter cache”, eu vou te dizer uma coisa sobre isso: É mentira!
TUDO, absolutamente TUDO pode ter cache, mesmo que ele seja de alguns segundos.
Casos extremos podem envolver o tempo de vida cache de 3, 2 ou até 1 segundo e ainda assim é possível que seja extremamente eficiente!
Eu não disse 1 minuto, eu disse 1 se-gun-do!!
Se você tem 2 mil requests por segundo a uma determinada página, que por sua vez faz 1 query para entregar a resposta, ter um cache de 1 segundo fará você eliminar 1999 acessos a banco por segundo. Saindo de 2k acessos a banco por segundo par 1.
A falácia do cache de 1 segundo não servir para nada!
Cache é ineficiente quando ele não é acessado, ou seja, quando o item é criado no cache e não é reaproveitado nunca ou somente poucas vezes. Dependendo do esforço para a criação desse objeto, até com pouco consumo é possível que seja eficiente.
Não existe tempo máximo e mínimo para o cache, existe cache que tem muito uso ou pouco uso.
Cache com pouco uso, precisa ser repensado para que tenha mais uso.
Cache com muito uso, está ótimo!!! Está cumprindo seu papel!
Reduzindo acesso ao banco
Vamos supor que para exibir um produto em uma página de um e-commerce seja necessário consultar:
- Informações básicas do produto na página
- Lista de imagens do produto
- Campos adicionais (aqueles campos malucos, como voltagem, tamanho, cor etc)
- Itens relacionados
- Preço/Disponibilidade
Na superfície, como usuário, dá para pensar nessas 5 consultas.
Eu acredito que com as variações de promoção, marketplace e etc isso tem potencial de ser bem pior. Daria para pensar em umas 15 queries. Mas vamos trabalhar com 5, pois é um bom número.
Vamos ignorar o tamanho do catálogo (quantidade de produtos diferentes), isso não tem utilidade para esse exemplo.
Se eu tenho 100 pageviews em na página de um único produto, isso se traduz em 500 queries.
Se forem 1000 pageviews, são 5k queries.
Vamos imaginar: 100 pageviews por segundo, durante 1 minuto.
100 * 60 = 6000 pageviews e 300.000 queries.
A primeira decisão inteligente com base nesse problema é pensar em cache.
Vamos pensar que o cache para o produto seja de 30 segundos.
Vamos pensar que o cache para o preço/disponibilidade seja de 3 segundos.
Ao invés de 300.000 queries no minuto, estamos falando de 20 queries (preço/disponibilidade) + 2 queries (produto) ou seja 22 queries por minuto.
Reduzindo acesso à aplicação
Se de um lado trabalhamos com o Redis para otimizar a forma como lidamos com os acessos à banco, agora podemos repensar se não é possível evitar o acesso à aplicação mesmo.
Vamos supor que existe uma página em um e-commerce. Por mais que o objeto seja produzido com base em uma query em 10 tabelas, se você consegue determinar em um CDN um tempo de cache para a página, você já está resolvendo boa parte dos problemas.
Então parte do desenho da aplicação muda para que alguns endpoints sejam mais cacheáveis ou seja, ele deixam de levar em conta a sessão do usuário para que endpoints específicos lidem com isso. Dessa forma o processamento do ASP.NET, por exemplo, só devolveria HTML genérico independente do usuário. Enquanto isso, chamadas específicas usando javascript, vão bater em endpoints que lidam com a sessão do usuário, fazendo assim com que a página seja modificada no cliente.
Esse é um típico cenário usado em CEP e em alguns casos até preço.
Se você trabalha com um SPA, você já está fazendo isso!
O que estamos ganhando aqui é mais fôlego para atender mais clientes, mais demanda.
Reduzindo acesso ao Web server
Todo computador tem um limite de conexões de rede possíveis, todo o webserver também. Além disso temos limites de banda dos cloud providers, sem contar aqueles que tarifam tráfego.
CDN’s podem reduzir drasticamente o acesso ao seu webserver, principalmente para javascripts, imagens, css e outros assets. Nesse caso, não só deixamos os assets no CDN que lida em entregar a versão mais próxima do cliente, mas também vamos reduzir a pressão sobre o Webserver, possibilitando que ele funcione melhor.
Conclusão
O pensamento é esse: Ser mais eficiente, e só processar o que é necessário, para conseguir processar mais.
Note que 3 segundos de tempo de vida de um cache pode parecer pouco, mas quando falamos em 300, 600, 1000 queries nessa janela de tempo, percebemos quanto ganhamos com o cache.
Nesse contexto, estamos desafogando o banco, que pode atender a tarefas prioritárias como escritas.
As consultas não deixam de chegar ao banco, só paramos de fazer repetidas vezes a mesma consulta, o que em outro momento afogaria o banco de dados.
O que estamos buscando é consumir o banco de forma mais eficiente, e buscamos diversos artifícios para fazer isso.
Um cache com Redis, é uma ótima forma de tratar isso, mas podemos trabalhar com output cache do asp .net por exemplo, ou ainda cache no nível do API Gateway.
Outra coisa que pode ser importante e pode dar fôlego à sua aplicação é fazer com que o webserver pare de entregar CSS, Javascripts e imagens, os assets em geral. Isso pode facilmente ser delegado a um serviço como um CDN. Isso reduz substancialmente as conexões a seu webserver.
Então se estamos buscando escala e atender um workload maior, esse é um bom tema a ser cogitado também!
Ainda nessa série vamos abordar esses temas, inclusive uma outra forma de reduzir o load de banco nos processos batch.
0 comentários