Vinicius Quinafelex Alves

🌐English version

Dicas de escalabilidade

Em computação, escalabilidade é a capacidade de um sistema de lidar com cargas e solicitações crescentes. Em outras palavras, o quanto um sistema aguenta quando precisa funcionar com um grande volume de usuários, requisições ou dados, e o quão simples e barato é aumentar essa capacidade.

O conceito está relacionado com performance, mas as definições podem ser diferentes. Performance costuma se referir a quanto tempo uma operação leva, enquanto escalabilidade foca mais em quantas operações simultâneas o sistema consegue suportar sem quebrar. Note que em alguns cenários de testes, escalabilidade é considerado um dos indicadores de performance.

Sistemas com escalabilidade ruim tem um limite estabelecido de quanto processamento ele consegue suportar. Isso pode limitar o crescimento das empresas, pois o aumento de usuários ou dados pode acabar quebrando o software.

Abaixo está listado alguns insights sobre como pode ser possível aumentar e manter a escalabilidade de sistemas:

Use ferramentas com escalabilidade horizontal

Considere usar bancos de dados que possuem escalabilidade nativa, como MongoDB, ao invés de bancos como SQL. Bancos não-escaláveis normalmente só aumentam a capacidade verticalmente, aonde o custo aumenta exponencialmente. Dispersar os bancos de dados entre clientes diferentes ou diferentes microsserviços podem ser estratégias válidas.

Pense na possibilidade de publicar aplicações web com mecanismos que permita adicionar instâncias com load balancing, como publicar em kubernetes ou outro serviço cloud equivalente. Quando a demanda do sistema aumenta muito, é mais fácil criar mais instâncias do que super-otimizar o código.

Use recursos com sabedoria

Se utilizar algum recurso que não pode ser escalado horizontalmente, mantenha seu consumo no mínimo. Consumir esse tipo de recurso diretamente eventualmente fará ele se tornar um gargalo.

Não abuse do uso de memória ou processador, especialmente em recursos não escaláveis. Tentar aumentar a performance consumindo mais memória ou processador pode prejudicar a escalabilidade a longo prazo, e deve ser feito com cautela.

Otimize as ferramentas externas. Por exemplo, se usar um banco de dados SQL, crie e use índices apropriadamente, evite operações que leiam ou escrevam muitos dados, ou evite sobrecarregar a memória quando trabalhar com tabelas temporárias.

Faça uso otimizado das threads através de programação assíncrona, por exemplo usando async e await do C#. Este link leva a um artigo escrito sobre assincronia.

Quando trabalhar com grandes coleções, opte por utilizar estratégias de streaming ao invés de carregar tudo em memória, por exemplo usando o yield o C#. Este link leva a um artigo escrito sobre yield e IEnumerable.

Infraestrutura a seu favor

É interessante cachear dados e resultados que não mudam com frequência. Além de serem relativamente simples de gerenciar, resultados cacheados evitam os gastos de recursos pra gerar resultados com os mesmos dados toda requisição, e ajudam na performance de processamento. Cacheamento é especialmente útil quando evita o consumo de recursos não-escaláveis.

Aplique coalescência de chamadas nas funções e requisições não-mutáveis e que são chamadas com frequência. Essa técnica faz com que diferentes chamadas pra uma mesma função e que retornam o mesmo resultado não precisa ser processado múltiplas vezes - basta propagar o resultado da primeira requisição para as demais e todos receberão os mesmos dados. Eu criei uma biblioteca C# thread-safe que permite tanto a coalescência como um cache em memória, chamado TimedDictionary.

Execute apenas o que for necessário, e evite funções genéricas que criam e retornam muito mais dados do que é necessário para concluir uma execução. Tente manter um balanço entre praticalidade e otimização.