Balanceamento de carga

Concluído

Aumentar horizontalmente ao colocar novas VMs online quando o tráfego aumenta é uma estratégia eficaz para o dimensionamento satisfazer a procura. O facto de as VMs poderem ser aprovisionadas rapidamente é essencial para alcançar a elasticidade. No entanto, colocar servidores adicionais online só será útil se o tráfego for distribuído entre os mesmos. De modo geral, isto ajuda o sistema a processar mais carga. É por isso que o balanceamento de carga é tão essencial para a elasticidade, uma vez que ajusta dinamicamente o número de recursos dedicados a uma tarefa.

A necessidade de balanceamento de carga resulta de dois requisitos básicos. Primeiro, o débito é melhorado pelo processamento paralelo. Se um único servidor conseguir processar cinco mil pedidos por unidade de tempo, 10 servidores com um balanceamento de carga perfeito conseguirão processar 50 mil pedidos por unidade de tempo. Segundo, os recursos com balanceamento de carga produzem maior disponibilidade. Em vez de encaminhar um pedido para um servidor que já tem dificuldade em acompanhar, um balanceador de carga pode direcionar o pedido para um servidor com uma carga mais leve. Além disso, se um servidor ficar offline e o balanceador de carga o reconhecer, poderá direcionar os pedidos para outros servidores.

O que é o balanceamento de carga?

Uma forma bem conhecida de balanceamento de carga é o DNS round robin, que muitos serviços Web grandes utilizam para distribuir pedidos entre vários servidores. Especificamente, vários servidores de front-end, cada um com um endereço IP exclusivo, partilham um nome DNS. Para equilibrar o número de pedidos em cada servidor Web, grandes empresas como a Google mantêm e organizam um conjunto de endereços IP para cada entrada DNS. Quando um cliente faz uma solicitação (por exemplo, para www.google.com), o DNS do Google seleciona um dos endereços disponíveis do pool e o envia para o cliente. A estratégia mais simples empregada para distribuir endereços IP é utilizar uma fila round robin em que, depois de cada resposta DNS, a lista de endereços é permutada.

Antes do aparecimento da cloud, o balanceamento de carga DNS era uma forma simples de reduzir a latência das ligações de longa distância. O distribuidor no servidor DNS era programado para responder com o endereço IP do servidor geograficamente mais próximo do cliente. A forma mais fácil de o fazer era responder com o endereço IP do conjunto numericamente mais próximo do endereço IP do cliente. Este método não era fiável, uma vez que os endereços IP não são distribuídos numa hierarquia global. As técnicas atuais são mais sofisticadas e dependem de um mapeamento de software de endereços IP para localizações com base em mapas físicos de Fornecedores de Serviços Internet (ISPs). Como este mapeamento é implementado como uma pesquisa de software cara, este método produz resultados melhores, mas a computação é dispendiosa. No entanto, o custo de uma pesquisa lenta é amortizado, uma vez que a pesquisa de DNS ocorre apenas quando é feita a primeira ligação a um servidor pelo cliente. Todas as comunicações subsequentes ocorrem diretamente entre o cliente e o servidor que possui o endereço IP distribuído. Pode ver um exemplo de esquema de balanceamento de carga DNS na Figura 9.

Figura 9: Balanceamento de carga em um ambiente de nuvem.

Figura 9: Balanceamento de carga em um ambiente de nuvem.

A desvantagem deste método está numa falha de servidor: a comutação para um endereço IP diferente depende da configuração TTL (Time-To-Live) da cache DNS. As entradas DNS são conhecidas como sendo de longa duração e as atualizações demoram mais de uma semana a serem propagadas. Isto significa que é difícil "ocultar" rapidamente uma falha do servidor do cliente. A redução da validade (TTL) de um endereço IP na cache melhora este fator ao custo do desempenho e ao aumentar o número de pesquisas.

O balanceamento de carga moderno refere-se frequentemente à utilização de uma instância dedicada (ou de um par de instâncias) para distribuir os pedidos recebidos pelos servidores de back-end. Para cada pedido recebido numa porta especificada, o balanceador de carga redireciona o tráfego para um dos servidores de back-end com base numa estratégia de distribuição. Ao fazê-lo, o balanceador de carga mantém os metadados do pedido, incluindo informações como cabeçalhos de protocolo das aplicações (por exemplo, cabeçalhos HTTP). Nesta situação, ter informações obsoletas não é uma preocupação, uma vez que cada pedido passa pelo balanceador de carga.

Embora todos os tipos de balanceadores de carga da rede encaminhem os pedidos juntamente com qualquer contexto para os servidores de back-end, quando se trata de servir a resposta de volta ao cliente, podem utilizar uma de duas estratégias básicas1:

  • Utilização do Proxy – nesta abordagem, o balanceador de carga recebe a resposta do back-end e transmite-a de volta ao cliente. O balanceador de carga comporta-se como um proxy Web padrão e está envolvido em ambas as metades de uma transação de rede, nomeadamente ao encaminhar o pedido para o cliente e ao enviar a resposta de volta.

  • Handoff TCP – nesta abordagem, a ligação TCP ao cliente é entregue ao servidor de back-end e o servidor envia a resposta diretamente ao cliente, sem passar pelo balanceador de carga.

A última destas estratégias está ilustrada na Figura 10.

Figura 10: Mecanismo de transferência TCP do dispatcher para o servidor back-end.

Figura 10: Mecanismo de transferência TCP do dispatcher para o servidor back-end.

Benefícios do balanceamento de carga

Um dos benefícios do balanceamento de carga é ajudar a mascarar as falhas num sistema. Desde que o cliente esteja exposto a um único ponto final que represente vários recursos, as falhas em recursos individuais ficam ocultas do cliente ao servir os pedidos com outros recursos. No entanto, agora o balanceador de carga torna-se num ponto único de falha. Se falhar por qualquer motivo, mesmo que todos os servidores de back-end ainda estejam a funcionar, os pedidos do cliente não serão processados. Consequentemente, para alcançar uma elevada disponibilidade, os balanceadores de carga são geralmente implementados aos pares.

O mais importante é que o balanceamento de carga melhora a capacidade de resposta ao distribuir as cargas de trabalho por vários recursos de computação na cloud. Ter uma única instância de computação na cloud tem várias limitações. Os módulos anteriores abordaram a limitação física em termos de desempenho, em que são necessários mais recursos para aumentar as cargas de trabalho. Com o balanceamento de carga, as cargas de trabalho maiores são distribuídas por vários recursos para que cada um possa satisfazer os respetivos pedidos de forma independente e paralela, o que melhora o débito da aplicação. O balanceamento de carga também melhora os tempos médios de resposta, uma vez que existem mais servidores para processar a carga de trabalho.

As verificações de estado de funcionamento são fundamentais para implementar estratégias de balanceamento de carga bem-sucedidas. Um balanceador de carga precisa de saber quando um recurso fica indisponível para poder evitar o encaminhamento do tráfego para esse recurso. A monitorização ping-echo, em que os servidores do balanceador de carga "enviam pings" com pedidos ICMP (Internet Control Message Protocol), é uma das táticas mais populares utilizadas para verificar o estado de funcionamento de recursos específicos. Além de considerar o estado de funcionamento de um recurso ao encaminhar o tráfego para este, algumas estratégias de balanceamento de carga são fatores noutras métricas, como débito, latência e utilização da CPU.

Os balanceadores de carga geralmente devem garantir uma elevada disponibilidade. A forma mais simples de fazer isso é ao criar várias instâncias de balanceamento de carga (cada uma com um endereço IP exclusivo) e associá-las a um único endereço DNS. Sempre que um balanceador de carga falhar por algum motivo, é substituído por um novo e todo o tráfego é passado para a instância de ativação pós-falha com impacto mínimo no desempenho. Simultaneamente, pode ser configurada uma nova instância do balanceador de carga para substituir a que falhou e os registos DNS devem ser imediatamente atualizados.

Além de distribuir pedidos entre servidores de back-end, os balanceadores de carga geralmente empregam mecanismos para reduzir a carga nos servidores e melhorar o débito geral. Alguns desses mecanismos incluem:

  • Descarga de SSL – as ligações HTTPS incorrem em custos de desempenho, uma vez que o respetivo tráfego é encriptado. Em vez de servir todos os pedidos através do protocolo SSL (Secure Sockets Layer), a ligação do cliente ao balanceador de carga pode ser feita por SSL, enquanto que os pedidos de redirecionamento para cada servidor são feitos por HTTP não encriptado. Esta técnica reduz consideravelmente a carga nos servidores. Além disso, a segurança é mantida desde que os pedidos de redirecionamento não sejam feitos numa rede aberta.

  • Colocação na memória intermédia de TCP – estratégia para descarregar clientes com ligações lentas ao balanceador de carga para aliviar os servidores que estão a servir as respostas a esses clientes.

  • Colocação na cache – em determinados cenários, o balanceador de carga pode manter uma cache para os pedidos mais populares (ou pedidos que podem ser processados sem acederem aos servidores, como conteúdos estáticos) para reduzir a carga nos servidores.

  • Modelação do tráfego – um balanceador de carga pode utilizar essa técnica para atrasar ou reclassificar o fluxo de pacotes para otimizar o tráfego para a configuração do servidor. Isto afeta o QoS para alguns pedidos, mas garante que a carga de entrada pode ser servida.

É importante lembrar que o balanceamento de carga só funciona se o balanceador de carga não estiver sob uma carga insuperável. Caso contrário, o balanceador de carga torna-se o estrangulamento. Felizmente, os balanceadores de carga tendem a realizar pouco processamento nos pedidos que recebem, em vez de dependerem de servidores de back-end para fazer o trabalho real de transformar os pedidos em respostas.

Distribuição equitativa

Existem várias estratégias de balanceamento de carga utilizadas na cloud. Uma das mais comuns é a distribuição equitativa, que utiliza um algoritmo round robin simples para distribuir o tráfego uniformemente entre todos os nós. Não leva em consideração a utilização de recursos individuais no sistema, nem é um fator em termos de tempo de execução do pedido. Esta abordagem tenta manter cada nó no sistema ocupado e é uma das mais simples de implementar.

O AWS utiliza esta abordagem na oferta Elastic Load Balancer (ELB). O ELB aprovisiona balanceadores de carga que equilibram o tráfego entre as instâncias EC2 anexadas. Os balanceadores de carga são essencialmente instâncias EC2 com um serviço para encaminhar o tráfego especificamente. Como os recursos por trás do balanceador de carga são aumentados horizontalmente, os endereços IP dos novos recursos são atualizados no registo DNS do balanceador de carga. Este processo demora vários minutos a ser concluído, uma vez que exige tempo de monitorização e de aprovisionamento. Este período de dimensionamento, que é o tempo de espera até o balanceador de carga estar pronto para processar a carga mais alta, é conhecido como "aquecimento" do balanceador de carga.

Os balanceadores de carga do AWS também monitorizam os recursos anexados para distribuição da carga de trabalho, de forma a manter uma verificação do estado de funcionamento. É utilizado um mecanismo ping-echo para garantir que todos os recursos estão em bom estado de funcionamento. Os utilizadores do ELB podem configurar os parâmetros da verificação de estado de funcionamento ao especificar os atrasos e o número de tentativas.

Distribuição baseada em hashes

Esta abordagem tenta garantir que os pedidos do mesmo cliente durante uma sessão são direcionados para o mesmo servidor sempre através de hashing de metadados que define cada pedido e ao utilizar o hash para escolher um servidor. Se o hashing for feito corretamente, os pedidos serão distribuídos de forma relativamente uniforme entre os servidores. Um benefício desta abordagem é a possibilidade de ser utilizada nas aplicações com reconhecimento de sessão, que podem armazenar os dados da sessão na memória, em vez de gravá-los num arquivo de dados partilhado, como uma base de dados ou cache de Redis. Uma desvantagem é que cada pedido tem de ser transformado em hash, o que introduz uma pequena quantidade de latência.

O Balanceador de Carga do Azure utiliza um mecanismo baseado em hashes para distribuir as cargas. Este mecanismo cria um hash para cada pedido com base no IP de origem, porta de origem, IP de destino, porta de destino e tipo de protocolo para garantir que, em circunstâncias comuns, todos os pacotes da mesma sessão são enviados para o mesmo servidor de back-end. A função de hash é escolhida para que a distribuição de ligações a servidores seja aleatória.

Outras estratégias de balanceamento de carga

Se um determinado servidor estiver a sobrecarregar o processamento de um pedido (ou um conjunto de pedidos), os balanceadores de carga que utilizam algoritmos de distribuição de round robin ou baseados em hashes encaminharão os pedidos para esse servidor de qualquer forma. Existem outras estratégias mais sofisticadas para efetuar o balanceamento de carga em vários recursos que têm a capacidade em consideração. Duas das métricas mais utilizadas para a capacidade de medição são:

  • Tempo de execução do pedido – as estratégias baseadas nesta métrica utilizam um algoritmo de agendamento de prioridade, no qual os tempos de execução do pedido são utilizados para escolher o destino dos pedidos individuais. O principal desafio desta abordagem é avaliar com precisão os tempos de execução. Um balanceador de carga consegue adivinhar os tempos de execução ao utilizar (e atualizar constantemente) uma tabela na memória que armazena as diferenças entre a hora em que um pedido é encaminhado para cada servidor e a hora a que regressa.

  • Utilização de recursos – as estratégias baseadas nesta métrica utilizam a CPU para equilibrar a utilização entre os nós. O balanceador de carga mantém uma lista ordenada de recursos com base na respetiva utilização e direciona cada pedido recebido para o recurso com a carga menor.

O balanceamento de carga é crucial para implementar serviços cloud dimensionáveis. Sem um meio eficaz de distribuir o tráfego pelos recursos de back-end, a elasticidade obtida com a criação de recursos quando são necessários e o desaprovisionamento quando não são é extremamente limitada.

Referências

  1. Aron, Mohit e Sanders, Darren e Druschel, Peter e Zwaenepoel, Willy (2000). "Distribuição escalável de solicitações com reconhecimento de conteúdo em servidores de rede baseados em cluster." Atas da Conferência Técnica Anual USENIX 2000.

Verifique o seu conhecimento

1.

Considere o seguinte cenário: está a utilizar um balanceador de carga com um agendador round robin como front-end para dois servidores Web. Um servidor Web é uma instância média que contém 2 núcleos e 8 GB de RAM, enquanto o outro é uma instância grande com 4 núcleos e 16 GB de RAM. Qual dos cenários seguintes é provável?