• Nenhum resultado encontrado

Sistema de Balanceamento de Carga Independente da Aplicação

N/A
N/A
Protected

Academic year: 2021

Share "Sistema de Balanceamento de Carga Independente da Aplicação"

Copied!
82
0
0

Texto

(1)

CENTRO DE CIÊNCIAS EXATAS E DA TERRA

DEPARTAMENTO DE INFORMÁTICA E MATEMÁTICA APLICADA BACHARELADO EM CIÊNCIA DA COMPUTAÇÃO

Sistema de Balanceamento de Carga

Independente da Aplicação

Juliano Cardoso de Mendonça

Natal - RN Novembro de 2017

(2)

Sistema de Balanceamento de Carga Independente

da Aplicação

Monografia de Graduação apresentada ao Departamento de Informática e Matemática Aplicada (DIMAp) da Universidade Federal do Rio Grande do Norte como requisito para a obtenção do grau de bacharel em Ciência da Computação.

Orientador

Profº Dr. Marcos César Madruga Alves Pinheiro

Universidade Federal do Rio Grande do Norte – UFRN Departamento de Informática e Matemática Aplicada – DIMAp

Natal - RN Novembro de 2017

(3)
(4)

aceita pelo Departamento de Informática e Matemática Aplicada do Centro de Ciências Exatas e da Terra da Universidade Federal do Rio Grande do Norte, sendo aprovada por todos os membros da banca examinadora abaixo especificada:

__________________________________________ Profº Dr. Marcos César Madruga Alves Pinheiro

Orientador

Departamento de Informática e Matemática Aplicada (DIMAp) Universidade Federal do Rio Grande do Norte (UFRN)

__________________________________________ Profº Me. Aluízio Ferreira da Rocha Neto

Instituto Metrópole Digital (IMD)

Universidade Federal do Rio Grande do Norte (UFRN)

__________________________________________ Profº Me. Carlos Gustavo Araújo da Rocha

Instituto Federal do Rio Grande do Norte (IFRN) Universidade Federal do Rio Grande do Norte (UFRN)

(5)

Dedico este trabalho a minha esposa, Mariana, a minha filha, Luna Beatriz, a minha mãe, Maria das Graças e a meus avós, Cícero e Dona Maria “branca”.

(6)

Seria impossível conseguir chegar até aqui sem a ajuda de alguém. Portanto, agradeço a Deus por ter me dado oportunidade e condições de realizar o sonho da graduação.

A minha mãe, Maria das Graças Cardoso de Mendonça.

A minha avó, Maria do Carmo dos Santos, por todo carinho, dedicação, incentivo e esforço para me educar.

A minha esposa, Mariana Cristina Pimenta Rodrigues Cardoso, por toda paciência, apoio e cumplicidade nas árduas madrugadas de estudo.

Aos meus amigos de faculdade, que me ajudaram nos semestres tenebrosos e sempre me incentivaram a nunca desistir.

A meus amigos de infância que, embora distantes agora, me fizeram suportar, com a lembrança dos seus sorrisos e abraços, toda carga física e intelectual da qual experimentei.

A coordenação do curso de Ciência da Computação e todo os integrantes do DIMAp, pelo auxílio e compreensão.

Enfim, ao meu orientador Dr. Marcos César Madruga Alves Pinheiro, por toda a ajuda nas correções; por toda paciência e incentivo nesta etapa final.

(7)

"Para nós, que compreendemos o significado da vida, os números não têm tanta importância."

(8)

Sistema de Balanceamento de Carga Independente

da Aplicação

Autor: Juliano Cardoso de Mendonça Orientador: Profº Dr. Marcos César Madruga Alves Pinheiro

R

ESUMO

Com o crescimento no uso das redes por pessoas e dispositivos houve um aumento significativo no volume do tráfego gerado, dificultando a utilização de ferramentas que precisam processar esse tráfego. Hoje, muitas empresas ou instituições possuem essa necessidade de processamento, devido a fatores como segurança de dados, por exemplo. Para isso, há diversas aplicações (como Firewalls, IDS, Anti-Spam, e analisadores de log) que podem ser instaladas em dispositivos, para tal fim. Entretanto, por causa de limites físicos e custos relativamente altos das suas aquisições, opta-se por implementações que envolvam técnicas de virtualização e cluster com balanceamento de carga. Neste modelo cada instância do cluster fica responsável por uma parcela do tráfego. Este estudo propõe um mecanismo de balanceamento de carga baseado em funções hash que pode ser usado em qualquer servidor independente da aplicação. Para validar a proposta foi implementada uma solução no kernel do Linux e foram realizados experimentos que comprovam redução de carga em cada servidor do cluster.

(9)

Figura 1. Capacidade de endereçamento dos protocolos IPv4 e IPv6 ... 16

Figura 2. Crescimento da IoT nos últimos anos ... 17

Figura 3. Camadas do sistema operacional ... 22

Figura 4. Detalhes do kernel ... 23

Figura 5. Fluxo de um pacote no kernel Linux ... 25

Figura 6. Ponteiros do skbuff na camada de transporte ... 28

Figura 7. Headroom e Tailroom ... 29

Figura 8. Estruturas do skbuff ... 30

Figura 9. Ponteiros da API de rede do Kernel ... 31

Figura 10. Taxonomia de escalonamento ... 33

Figura 11. Taxonomia mais compacta do escalonamento ... 34

Figura 12. Modelo de escalonamento generalizado para sistemas distribuídos ... 36

Figura 13. Escalabilidade horizontal ... 38

Figura 14. Escalabilidade Vertical ... 39

Figura 15. Balanceador de carga ... 45

Figura 16. Modelo do balanceador Microsoft Azure ... 47

Figura 17. Modelo do balanceador AWS ... 49

Figura 18. Modelo do balanceador NGINX ... 50

(10)

Figura 21. Método LVS via IP Tunneling ... 54

Figura 22. Método LVS via Direct Routing ... 55

Figura 23. Esquema matemático do balanceador de carga ... 57

Figura 24. Arquitetura proposta do trabalho ... 59

Figura 25. Função Hash ... 61

Figura 26. Funcionamento da arquitetura proposta ... 63

Figura 27. Arquitetura proposta do trabalho ... 67

Figura 28. Experimento 1: Comparação entre o processamento nos servidores ... 72

Figura 29. Experimento1: Comparação entre a média do número de conexões em cada servidor ... 73

Figura 30. Experimento2: Distribuição da sobrecarga do Servidor1 ... 74

Figura 31. Experimento 2: Distribuição do número médio de conexões ... 75

Figura 32. Experimento 3: Distribuição da sobrecarga entre os balanceadores ... 76

Figura 33. Experimento 3: Distribuição das conexões entre os balanceadores ... 77

(11)

Tabela 1. Definições dos hooks do Netfilter ... 24 Tabela 2. Siginificado das macros do Netfilter ... 25 Tabela 3. Representa, em b1, a relação entre identificador e endereços MAC

... 64

Tabela 4. Representa, em b0, a relação entre identificador e endereços MAC

(12)

Lista de abreviaturas e siglas

ARP. Protocolo de Resolução de Endereços – do inglês Address Resolution Protocol

BC. balanceador de carga

CPU. Unidade Central de Processamento – do inglês Central Process Unity DH. Destination Hashing

EC2. Nuvem de Computação Elastica - do inglês Elastic Compute Cloud ICMP. Internet Control Message Protocol

IDS. Sistemas de Detecção de Intrusão – do inglês Intrusion Detection

System

IoT. Internet das Coisas – do inglês Internet of Things

IPv4. Protocolo de Internet Versão 4 – do inglês Internet Protocol Version 4 IPv6. Protocolo de Internet Versão 6 – do inglês Internet Protocol Version 6 IPVS. Servidor Virtual de IP – do inglês IP Virtual Server

LBLC. Locality-Based Least-Connection

LBLCR. Locality-Based Least-Connection with Replication LC. Least-Connection

LDEC. Lista Duplamente Encadeada Circular

LVS. Linux Virtual Server

NAT. Tradução de Endereços de Rede – do inglês Network Address Translation

NQ. Never Queue

Programação de Aplicações - do inglês Application Programming Interface. Application Programming Interface

RAM. Memórias de Acesso Randômico – do inglês Random Access Memory RIP. IP dos Real Servers

RR. Round Robin

SAR. System Activity Reporter SED. Shortest Expected Delay SH. Source Hashing

SKB. Socket Buffer

SMP. Multiprocessamento Simétrico – do inglês Symmetric Multi-Processing

SO. Sistema Operacional

SP. Problema do Escalonamento - do inglês scheduling problem

TCP. Protocolo de Controle de Transmissão – do inglês Transmission Control

Protocol

TI. Tecnologia da Informação

(13)
(14)

Sumário

1 Introdução... 16 1.1 Objetivos ... 19 1.2 Organização do Trabalho ... 20 2 Referencial Teórico ... 21 2.1 Kernel ... 21 2.2 Netfilter ... 23 2.3 Skbuff ... 26 2.4 Escalonamento ... 32 2.5 Escalabilidade ... 37 2.6 Balanceamento de Carga ... 40 2.6.1 Algoritmos de balanceamento... 41 2.6.2 Tipos de Balanceamento ... 43 2.6.3 Balanceadores de cargas ... 43 3 Trabalhos Relacionados ... 46 3.1 Microsoft Azure ... 46

3.2 Amazon Web Services (AWS) ... 48

3.3 Nginx ... 49

3.4 HAProxy ... 50

3.5 Linux Virtual Server (LVS) ... 51

4 Implementação de um Balanceador de Carga para uma Aplicação Qualquer ... 56 4.1 Esquema Matemático ... 56 4.2 Arquitetura... 58 4.2.1 Ideia Geral ... 59 4.2.1.1 Algoritmo de hash ... 60 4.2.2 Funcionamento ... 62 5 Estudo de Caso ... 66 5.1 Topologia ... 66 5.2 Encaminhamento de tráfego TCP ... 67

(15)

6.2 Estrutura dos Experimentos ... 69

6.2.1 Experimentos ... 70

6.3 Resultados Obtidos ... 71

(16)

1 Introdução

O ser humano com sua imensa necessidade de comunicação pôde criar inúmeros serviços de Internet para diversas plataformas e dispositivos. Assim, hoje já não faz mais sentido o uso do termo redes de computadores, sendo mais adequado pensar em redes de dispositivos, dada a quantidade enorme de componentes distintos (canetas, smartphones, relógios, computadores, etc) que podem se conectar.

Ao longo dos anos, observou-se um crescente número de dispositivos conectados em rede a ponto de extrapolar a já elevada capacidade de endereços oferecidos pelo Protocolo de Internet Versão 4 – do inglês Internet

Protocol Version 4 (IPv4) e forçar a migração para o Protocolo de Internet

Versão 6 – do inglês Internet Protocol Version 6 (IPv6), apesar do uso de algumas técnicas para minimizar o problema, como a Tradução de Endereços de Rede – do inglês Network Address Translate (NAT) . A Figura 1 demonstra a comparação entre os protocolos.

Figura 1. Capacidade de endereçamento dos protocolos IPv4 e IPv6

Fonte: Eldweik (2017)

Dessa forma, no contexto atual é frequente o uso do termo Internet das Coisas – do inglês Internet of Things (IoT), que é definida por Atzori et al apud Gubbi et al (2013 p. 1646) como:

(17)

Internet of Things can be realized in three paradigms—internet-oriented(middleware), things oriented (sensors) and semantic-oriented (knowledge). Although this type of delineation is required due to the interdisciplinary nature of the subject, the usefulness of IoT can be unleashed only in an application domain where the three paradigms intersect.

A Figura 2 nos dá uma dimensão da estimativa do aumento da IoT, mostrando que o número de dispositivos conectados à Internet deverá ter um crescimento em torno de 75% entre os anos de 2017 até 2020.

Figura 2. Crescimento da IoT nos últimos anos

Fonte: Maxey (2015)

Fortemente influenciado por esse processo do surgimento da IoT, a enorme quantidade de dados que, a partir de então, passaram a ser armazenados em nuvem, produzia o que conhecemos agora como: BIG DATA. Segundo Casonato (2013, p. 4) apud Novo e Neves (2013, p. 33), Big Data são

ativos de informações com alto volume, velocidade e variedade que demandam formas eficientes e inovadoras de processamento dos dados para obtenção de insights melhorados e tomadas mais precisas de decisão.

(18)

Atualmente muitas empresas e diversas outras instituições compartilham informações, e o fazem de maneira a obter resultados relativamente rápidos de suas atividades, influenciadas pelo avanço da globalização, competitividade do mercado, pesquisas de inúmeras naturezas, etc. Além disso, as partes envolvidas na troca de informações tem a necessidade de garantia da segurança dos seus dados. Assim, elas precisam também serem capazes de manter as propriedades básicas da segurança da informação: confidencialidade, integridade, disponibilidade e autenticidade.

Visando atender aos requisitos de segurança, as instituições tipicamente fazem uso de um conjunto de ferramentas ou sistemas, entre os quais podemos citar: Firewalls, Sistemas de Detecção de Intrusão – do inglês

Intrusion Detection System (IDS), Anti-Spam, e analisadores de log. Entretanto,

decorrente do crescimento do número de dispositivos conectados e do tráfego gerado, a utilização dessas ferramentas de maneira centralizada se torna inviável devido aos elevados recursos computacionais necessários para analisar todo o tráfego.

A utilização de um único equipamento pode apresentar diversos problemas, como elevado custo, atraso no encaminhamento dos pacotes, e incapacidade de processar todo o tráfego. Soluções distribuídas tem se mostrado uma alternativa interessante para resolver essas limitações, mas muitas vezes são específicas para um determinado protocolo de aplicação. Ou seja, geralmente o cluster é criado para permitir a existência de diversos servidores de aplicação, como servidores Web e Proxies, que são o ponto final de uma conexão do Protocolo de Controle de Transmissão – do inglês

Transmission Control Protocol (TCP).

Neste contexto, esta monografia propõe uma solução para balanceamento de tráfego em um cluster de servidores, e de uma forma independente de protocolo de aplicação, de modo a reduzir os recursos computacionais necessários em cada nó. Os servidores desse cluster, em especial, tipicamente não são o ponto final de uma conexão, e podem ser

(19)

utilizados, também, para analisar ou processar o tráfego sendo encaminhado na rede. Os experimentos conduzidos neste trabalho focam no protocolo IPv4 e visam avaliar o desempenho entre as entidades de um cluster pelo balanceamento de carga feito através de um algoritmo baseado em hash. Vale salientar que embora não tenha sido realizada a implementação para o protocolo IPv6, a abordagem proposta se aplica igualmente a esse protocolo.

1.1 Objetivos

Esta subseção apresentará o objetivo geral do trabalho e as metas específicas para alcançá-lo. O presente trabalho se propõe a melhorar o desempenho da análise e processamento de pacotes em uma rede IP, através da utilização de um cluster de servidores, cuja técnica de balanceamento de carga utiliza um algoritmo baseado em hash.

● Objetivos gerais:

o Definir um mecanismo de balanceamento de carga voltado para a criação de um cluster de servidores de aplicação.

● Objetivos específicos:

o Propor uma técnica de balanceamento de carga definida por um algoritmo baseado em tabela de dispersão (hash table). Essa técnica deve garantir que os pacotes de uma conexão que atravessa o cluster passe sempre pelo mesmo servidor, independente do sentido do tráfego;

o Sugerir uma topologia na qual, independente da aplicação a ser balanceada, seja possível a implementação do referido balanceamento, através de dois balanceadores, um conectado à rede externa e outro à interna;

o Efetuar experimentos que comprovem que o balanceador não acarreta atraso significativo no encaminhamento dos pacotes, e reduz o consumo de recursos computacionais nos nós de análise/processamento do tráfego.

(20)

1.2 Organização do Trabalho

Este trabalho apresenta, no Capítulo 2, o referencial teórico, discorrendo sobre a temática em estudo, tais como: fluxo de informações, balanceadores de carga, relacionando suas características e dando uma visão mais ampliada acerca do conteúdo ao leitor, estrutura de dados skbuff, kernel do Linux, Netfilter, escalonamento e balanceamento de carga.

O Capítulo 3 apresenta os trabalhos relacionados, discutindo sobre algumas soluções de balanceamento de carga, que embasaram o trabalho ou motivaram, de alguma maneira.

O Capítulo 4 apresenta a arquitetura da solução proposta, discutindo seus componentes e o funcionamento do algoritmo de balanceamento de carga, também é definida a ideia genérica de um balanceador de carga (BC), para ilustrar e servir de parâmetro norteador.

O Capítulo 5 apresenta o estudo de casos, fazendo menção aos protocolos, envolvidos nos casos de uso. Este capítulo também ilustra a arquitetura de modo mais específico, no contexto dos casos de uso.

O Capítulo 6 fala sobre os experimentos, em que ambiente computacional foram realizados os testes, a estrutura da qual guiou a construção deles, os resultados coletados e suas respectivas análises.

O Capítulo 7 apresenta as considerações finais, abordando as dificuldades encontradas para a realização do projeto, e sugerindo possíveis desdobramentos dessa monografia.

(21)

2 Referencial Teórico

Este capítulo apresenta alguns conceitos que auxiliarão na compreensão do desenvolvimento do trabalho proposto. Inicialmente será apresentada a definição de kernel e a consequente separação entre os espaços do usuário e do kernel. Em seguida, será apresentado o framework Netfilter e a estrutura skbuff que é utilizada pelo Linux para manipulação dos pacotes. Por último, são apresentadas as definições sobre escalonamento e balanceamento de carga.

2.1 Kernel

Um sistema operacional (SO) é um software que tem a função de gerenciar os recursos e serviços do hardware de um computador; e seu núcleo é o kernel. Stevens e Rago (2013, p.1) trazem uma definição do kernel um pouco diferente

[...] an operating system can be defined as the software that controls the hardware resources of the computer and provides an environment under which programs can run. Generally, we call this software the kernel, since it is relatively small and resides at the core of the environment.

Eles afirmam que o kernel é o próprio sistema operacional e, em seguida, comentam sobre outras camadas que complementam este sistema, como pode-se observar na Figura 3.

(22)

Figura 3. Camadas do sistema operacional

Fonte: Stevens e Rago (2013, p. 2)

O Sistema Operacional Linux possui uma estrutura característica, onde todo o gerenciamento de recursos é controlado através de sinais de interrupção e chamadas de sistema. O Linux possui o conceito de User Space e Kernel Space a fim de garantir um certo grau de segurança no sistema. A comunicação realizada entre estes espaços utiliza funções para troca de informações, onde systems calls são requisitadas por processos de usuários e sinais de diversos tipos. Como explica Love (2010, p. 7)

Communication within the kernel is trivial because everything runs in kernel mode in the same address space: The kernel can invoke functions directly, as a user-space application might.

A Figura 4 ilustra esse mecanismo, destacando o User Space e o Kernel

(23)

Figura 4. Detalhes do kernel

Fonte: Mauerer (2004, p. 4)

Embora o kernel do Linux seja baseado no paradigma de monolithic

kernels ele nos permite registrar ou remover módulos no núcleo

dinamicamente. Mais adiante, são apresentados mais detalhes sobre as implementações dos módulos de kernel.

2.2 Netfilter

O Netfilter é um framework construído para auxiliar a construção de soluções de firewalls em um sistema Linux, no que se diz respeito à manipulação de pacotes. Como afirma Caesar (2012, p. 2) o Netfilter define essencialmente um conjunto de hooks1 dentro kernel do Linux que permite

aos módulos de kernel registrar funções callback com a pilha de rede. Esse conjunto indica onde o firewall pode aplicar suas regras, uma vez que cada

hook corresponde a uma área no sistema que é associada, basicamente, à

entrada de pacotes, encaminhamento ou saída. Mais especificamente, existem cinco hooks, como podemos ver na Tabela 1.

1 Áreas internas do Kernel onde funções podem ser registradas para eventuais invocações do

(24)

Tabela 1. Definições dos hooks do Netfilter

Hook A chamada Acontece

NF_INET_PRE_ROUTING Antes das decisões de roteamento.

NF_INET_LOCAL_IN Depois de tomar decisões de roteamento e se o pacote se destinar a este dispositivo.

NF_INET_FORWARD Quando um pacote é destinado a uma outra interface de rede diferente da que foi recebido.

NF_INET_LOCAL_OUT Para pacotes produzidos por processos locais e emitidos nas interfaces de saída.

NF_INET_POST_ROUTING Após as decisões de roteamento. Fonte: Baseada em Caesar (2012)

A ferramenta geralmente associada ao Netfilter é o Iptables. As regras do iptables são organizadas em tabelas (ex: filter, mangle e nat) e utilizam classificadores (parâmetros de filtragem, por exemplo, tipos de protocolos dos pacotes) para selecionar a uma ação a ser tomada (aceitação, encaminhamento, descarte de pacotes, etc). O Netfilter e o Iptables se complementam, pois um atua no espaço do kernel e o outro no espaço de usuário, respectivamente. Em outras palavras, pode-se dizer que o iptables é uma interface de alto nível para o Netfilter.

A Tabela 2 apresenta as definições dos códigos de retorno construídos pelo Netfilter e utilizados pelas ferramentas de firewalls.

(25)

Tabela 2. Siginificado das macros do Netfilter

Código de Retorno Significado

NF_DROP Descarta os pacotes.

NF_ACCEPT Mantém o fluxo normal do parcote no framework Netfilter e executa os demais hooks. NF_STOLEN Informa ao kernel que a função registrada no hook assumirá o controle do pacote. NF_QUEUE Insere o pacote em uma fila para o espaço do usuário. NF_REPEAT Envia o pacote e Invoca as funções subsequentes do hook novamente.

NF_STOP Armazena o pacote e desconsidera a execução dos demais hooks. Fonte: baseada em Caesar (2012).

Embora o Iptables forneça uma interface relativamente simples para controlar o tráfego, é possível escrever código e registrá-lo em qualquer hook do Netfilter para que este processe os pacotes. Esse código é escrito na linguagem de programação C e é executado no espaço de kernel.

Figura 5. Fluxo de um pacote no kernel Linux

(26)

Na Figura 5, podemos ver um pouco mais de detalhes a respeito do

framework Netfilter e como ele está integrado às outras funções da pilha de

rede do kernel Linux. Ela representa os caminhos possíveis que um pacote pode tomar a partir da recepção ou envio do mesmo. Quanto a recepção, o pacote passa pelo ponto de entrada, invocando a função ip_rcv() que inicia a execução das funções do hook PRE_ROUTING do Netfilter. Após isso, o sistema toma decisões de roteamento, decidindo se os pacotes são destinados à máquina local ou devem ser reencaminhados.

No caso de pacotes destinados ao host, eles são enviados ao hook

LOCAL_IN e em seguida, através da função ip_local_deliver(), são entregues ao

sistema. Entretanto, se os pacotes são destinados à um outro host, eles passam por um processo de encaminhamento, através da função ip_forward(), que depois de invocar as funções do hook FORWARD, os repassa ao ponto de saída, relacionado à função ip_output(). Daí, acontece a invocação das funções do hook POST_ROUTING e finamente os pacotes são retransmitidos na rede, com a execução da função dev_queue_xmit().

Em relação à transmissão de pacotes gerados pelo host local, há a execução da função ip_queue_xmit(), que invoca as funções do hook

LOCAL_OUT para que, depois do processo de roteamento, os pacotes sejam

transmitidos, através da função ip_output(), conforme descrito acima.

2.3 Skbuff

A sigla skbuff vem da expressão em inglês Socket Buffer (SKB), que, em outras palavras, significa uma estrutura de dados para o armazenamento e manipulação de informações, mais especificamente, o armazenamento de quadros ou pacotes de rede. A estrutura possui diversos ponteiros que a conectam e também apontam para as áreas de memória, onde estão os dados dos pacotes. Estes ponteiros servem para adicionar ou remover os cabeçalhos

(27)

dos protocolos quando os pacotes fluem pela pilha de Interconexão de Sistemas Abertos – inglês Open System Interconnection (OSI. Esse procedimento é realizado através das inúmeras funções presentes na estrutura SKB (definida em include/linux/skbuff.h), que ajudam na conversão de dados apropriada. Ainda de acordo com Mauerer (2008, p. 751)

The corresponding information from the transport header can be extracted with tcp_hdr, respectively, udp_hdr. Both functions convert the raw pointer into an appropriate data type. Other transport layer protocols also provide helper functions of the type XXX_hdr that require a pointer to struct sk_buff and return the reinterpreted transport header data. The basic idea of a socket buffer is to add and remove protocol headers by manipulating pointers.

Quando um pacote de dados é recebido pela placa de rede de um dispositivo, o driver da placa comunica, ao núcleo do SO, a presença desse conjunto de dados, a fim de repassá-lo ao núcleo para seu devido tratamento, como afirma Barbato e Montes (2004, p. 101)

[...] o driver da placa de rede é acionado para tratar a interrupção (ei_interrupt) gerada e iniciar o processo de recepção (ei_receive). O driver então, aloca (dev_alloc_skb) uma estrutura denominada sk_buff (include/linux/skbuff.h), que é a representação dos dados perante o kernel, extrai os dados da placa de rede e os coloca (ei_block_input) nesta estrutura, para finalmente invocar a rotina (netif_rx) responsável por transferí-los para estruturas internas do kernel5.

Neste momento o Kernel invoca funções específicas para manipular o pacote através da estrutura skbuff. Segundo comenta Goutelle et all (2004, p. 7) no código de rede, virtualmente muitas funções são invocadas com um

skbuff (a variável é geralmente chamada de skb) passada como um parâmetro.

Uma vez que o pacote pertença ao sistema, haverá um procedimento determinado para acolhê-lo no SO, caso contrário, realiza-se o encaminhamento do pacote ao seu destino real ou o descarte. O procedimento é feito quando o pacote é transmitido para o kernel, vindo do User Space (espaço do usuário) ou do driver da placa de rede.

(28)

No envio de pacotes a partir de um dispositivo, eles são gerados pelo sistema, e mantidos na memória do computador. Cada pacote é referenciado pelos ponteiros HEAD e END da estrutura SKB para, a partir daí, ser manipulado. Quando o pacote passa para a camada TCP, por exemplo, os ponteiros DATA e TAIL apontam para o início e fim do cabeçalho TCP, respectivamente, como mostra a Figura 6.

Figura 6. Ponteiros do skbuff na camada de transporte

Fonte: Mauerer (2008, p. 752)

Do mesmo modo, ao entrar na camada IP, há uma alteração nos ponteiros. Mas neste caso, apenas no DATA que apontará para o início do cabeçalho IP. Todo esse processo é repetido nas outras camadas, à medida em que acontece a transmissão do pacote na pilha de camadas do modelo OSI.

Um procedimento similar é feito quando o Socket de Buffer é repassado para o kernel, mas dessa vez os ponteiros são vistos pelas funções como deslocamentos relativos. Como já mencionado, a skbuff utiliza diversas funções que auxiliam na manipulação do datagram2 até seu envio definitivo.

Todas essas operações são utilizadas, também, para o recebimento, encaminhamento ou descarte de pacotes, de maneira análoga.

(29)

A seguir, vemos alguns métodos da estrutura SKB e seus detalhes. skb_headroom(const struct sk_buff*skb): de acordo com Rosen

(2014) esta função retorna o espaço livre, em bytes, da área

headroom. Ou seja, a diferença de bytes entre os ponteiros data

e head.

skb_tailroom(const struct sk_buff*skb): esta é análoga a anterior,

sendo relacionada à tailroom, neste caso, ela retorna a diferença de bytes entre tail e end. A Figura 7 apresenta isso, mais claramente.

Figura 7. Headroom e Tailroom

Fonte: Benvenuti (2006, p. 27)

(30)

fazer a abstração de uma lista de espera, composta por estruturas skbuff. Tais listas são usadas, por exemplo, quando a placa de rede lê os bytes que representam os pacotes e armazena-os nas estruturas skbuff’s. A estrutura

sk_buff_head possui dois ponteiros que apontam para as skbuff’s, permitindo

a montagem de uma Lista Duplamente Encadeada Circular (LDEC), que representa justamente a lista de espera, como pode ser observado na Figura 8.

Figura 8. Estruturas do skbuff

Fonte: Mauerer (2008, p. 754)

O driver da placa de rede entra em comunicação com as outras camadas da pilha de rede, manipulando o pacote com o skbuff, por meio do framework Netfilter. No decorrer desse processo, diversas funções do kernel são invocadas para manipular os datagramas, alocando espaço de memória e deslocando os ponteiros da skbuff, para o acesso dos cabeçalhos do pacote.

Podem ser elencadas algumas funções que deslocam os ponteiros da

skbuff, as quais podem ser invocadas pelos módulos de kernel para acessar

os cabeçalhos de um pacote de rede. A Figura 9, mostra o efeito do processo através das funções skb_put(), skb_push(), skb_pull() e skb_reverse(), respectivamente.

(31)

Figura 9. Ponteiros da API de rede do Kernel

Fonte: Benvenuti (2008, p. 33)

Nesta figura, de (a1) para (a2) representa-se o efeito do uso de skb_put(), que diminui a tailroom em n bytes, aumentando o tamanho da área de dados em n bytes, também. Essa operação é muito útil para criar espaço para

(32)

inserção de cabeçalhos de rede. Esse procedimento é análogo às outras funções apresentadas na Figura 9.

Uma maneira ainda mais simples de se deslocar os ponteiros para obter um cabeçalho específico do pacote é usar as funções ip_hdr(), icmp_hdr(),

udp_hdr() e tcp_hdr(). Elas recebem um ponteiro para a sk_buff e o tamanho

atual da área de dados, e retornam um ponteiro para os bytes que representam o cabeçalho específico. Isso pode evitar possíveis erros cometidos pelo programador na manipulação de ponteiros.

2.4 Escalonamento

Podemos pensar no escalonamento como uma maneira de atribuir tarefas para entidades de um sistema, mas, na verdade, o termo

escalonamento é amplamente debatido por especialistas no assunto, gerando

diferentes conceitos. De acordo com (SOUZA, 2000)

Genericamente, o que pode explicar essa situação é a falta de uma teoria básica e comum sobre escalonamento[...] Os pesquisadores acostumados a trabalhar diretamente com a computação paralela ou com os sistemas operacionais (distribuídos ou não), utilizam seus próprios termos, muitas vezes, para designar a mesma atividade.

Segundo (BESTAVROS, 1997) o escalonamento é classificado em um sistema multiprocessador como um problema NP-Hard3 e é ainda mais

exacerbado em um ambiente de sistemas distribuídos. Este problema sugere “decisões que possibilitam um aumento de desempenho.”, conforme (SABO, 2006), e serve para solucionar um outro: o balanceamento de carga. Falaremos dele com mais detalhes na seção 2.6.

O escalonamento pode ser classificado como global ou local. Neste trabalho, vamos focar no escalonamento global (ligado a sistemas

3 “Non-deterministic Polynomial-time hard (NP-hard) problems are those problems that are

impossible to obtain their optimal solution within a polynomial bounded computation time” (ALMUFTI, 2017 apud KARABOGA, 2007).

(33)

distribuídos), do qual deriva-se o escalonamento global estático e dinâmico. Podemos imaginar algum tipo de relação, tabela ou esquema usado na tomada de decisões por parte do computador. Do ponto de vista computacional estático, essa relação é gerada em tempo de compilação, enquanto que do dinâmico, é gerada em tempo de execução. A Figura 10 exibe uma visão geral da taxonomia do escalonamento.

Figura 10. Taxonomia de escalonamento

Fonte: Casavant & Kuhl (1998)

Uma outra abordagem (mais recente) da taxonomia do escalonamento é proposta por (ROMAN, et al., 2016) e pode ser vista na Figura 11. Ela é mais compacta e menos detalhada, porém foca nas características mais importantes do escalonamento, das quais já citamos a estática e a dinâmica. O autor trata do conceito de escalonamento como sendo sinônimo do balanceamento de carga.

(34)

Figura 11. Taxonomia mais compacta do escalonamento

Fonte: Roman et al. (2016, p. 446)

Para se ater ao escopo do trabalho, além das peculiaridades já discutidas, serão apresentadas apenas as seguintes: cooperativa, não-cooperativa, adaptativa e não-adaptativa.

A característica cooperativa de um sistema, consiste em seus elementos processarem determinadas tarefas com a ajuda de outros, já a não-cooperativa é voltada a elementos que executam tarefas de maneira exclusivamente individual, sem a intervenção de outros.

Um sistema também pode mudar sua política de escalonamento de tarefas, isto é, se uma determinada atribuição de tarefas causou um impacto significativamente positivo para o sistema de modo geral e a análise culminou em uma mudança de uma política A (menos eficiente) para uma política B (mais eficiente), então realiza-se a troca de políticas. Dessa forma, o sistema se molda de acordo com o estado atual de suas variáveis. Essa é uma característica adaptativa. Por outro lado, a não-adaptativa não leva em consideração o contexto atual do sistema como um todo.

(35)

Uma outra definição mais detalhada sobre o escalonamento pode ser vista no relatório “A Taxonomy of Job Scheduling on Distributed Computing Systems” de (LOPES; MENASCÉ, 2015). Ele propõe uma taxonomia unificada, em oposição às que foram projetadas para propósitos específicos (como a taxonomia grid, que abrange problemas de escalonamento multi-critério envolvendo custos, desconsiderando - segundo o autor - outros problemas de escalonamento que não tem a característica de custo ou não são multi-critério), argumentando que é possível unificá-las e com isso generalizar o problema do escalonamento. O relatório diz que esse problema consiste em atribuir recursos à consumidores no tempo, e fala ainda que deve especificar três componentes: carga de trabalho, recursos e requisitos.

Para (LOPES; MENASCÉ, 2015) a carga de trabalho é composta de jobs que correspondem a um conjunto de tarefas (tasks) computacionais. Ela consome os recursos do sistema.

Os recursos, por sua vez, são conjuntos de nós, entidades, componentes ou computadores que possuem uma conexão e um núcleo (core/multi-core) de processamento. Eles podem pertencer a ambientes amplamente distribuídos, sendo escaláveis em datacenters ou organizados em

clusters, localmente. Assume-se que tais recursos podem processar qualquer

tipo de tarefa computacional e que apenas se comunicam através de trocas de mensagens pela rede.

O último dos componentes a ser definido são os requisitos. Baseado no relatório, podemos pensar nos requisitos como um conjunto de restrições ou regras que determinam os objetivos do escalonamento, bem como o nível de detalhe que constitui a decisão do problema. Quanto aos objetivos, abrangem comumente a otimização de uma métrica ou uma combinação delas. Já ao nível, pode corresponder a jobs ou a tasks. O grau de detalhamento no nível de tasks é bem maior que no de jobs, obviamente, uma vez que compreende processos e threads em execução, entrando no escopo de sistemas operacionais e fugindo um pouco do pertinente a este trabalho.

(36)

Na visão do autor, tanto os recursos quanto às cargas de trabalho sofrem a ação do tempo, pois são componentes dinâmicos do sistema. Com isso ele considera um conjunto , que denota os instantes de tempo de interesse (discretos ou não). A cada instante a carga de trabalho é composta por um conjunto e os recursos por um conjunto . No caso, os recursos podem falhar ou se tornar indisponíveis em algum momento, por isso a consideração de seu aspecto dinâmico.

Figura 12. Modelo de escalonamento generalizado para sistemas distribuídos

Fonte: Lopes & Menascé. (2015, p. 8)

A Figura 12 exibe a ideia dos autores por meio de um esquema arquitetural. Nele podemos verificar o fluxo dos jobs provindos das requisições dos usuários, produzindo cargas de trabalho a serem distribuídas (através de políticas de escalonamento, tanto no nível de tasks quanto no de jobs) e consumidas pelos recursos no tempo.

Por fim (de maneira estática), seja W, R e Q os conjuntos que representam, respectivamente, as cargas de trabalho, os recursos do sistema e os requisitos a serem satisfeitos. Podemos apresentar a definição do Problema do Escalonamento - do inglês scheduling problem (SP) proposta no relatório como a tupla (W, R, Q). A cada um desses conjuntos é atribuído

(37)

características que os descrevem com maior detalhamento, no relatório, e auxilia na definição - por exemplo - do problema do balanceamento de carga. É importante salientar que a solução do escalonamento (SS - do inglês

scheduling solution) deve ser sempre associada um dado problema do

escalonamento (LOPES; MENASCÉ,2015,p.3).

Em nosso trabalho, vamos nos basear nas taxonomias de (CASAVANT & KUHL, 1998) e (LOPES & MENASCÉ, 2015) para definir o problema do balanceamento de carga e nossa arquitetura proposta. Não é o objetivo desse trabalho, dá uma nova definição ao problema do escalonamento, nem apontar sua diferença ou equivalência ao do balanceamento de cargas.

2.5 Escalabilidade

Existem diferentes conceitos de escalabilidade na literatura, devido à grande quantidade de dimensões a que o termo pode se referir, conforme discute (PORTO, 2009) em sua dissertação, “escalabilidade é um tópico multidimensional”. De uma maneira informal para (PACHECO, 2011) uma tecnologia é escalável se ela pode lidar com o tamanho do problema cada vez maior. Mas de acordo com (PORTO, 2009) a escalabilidade pode ser definida como “a capacidade de um sistema de acomodar cargas de trabalho variantes, enquanto continua a satisfazer todos os seus outros requisitos: funcionais, não funcionais, etc.” Quando se “continua a satisfazer todos os seus outros requisitos”, é como se o sistema mantivesse seu desempenho constante ou pudesse aumentá-lo, pois de uma maneira ou de outra, isso implica que o sistema continua a satisfazer seus requisitos.

Sabe-se que há uma forte relação entre escalabilidade e desempenho, ainda segundo o autor a “influência do desempenho na escalabilidade é direta, aumentando o desempenho aumenta-se a escalabilidade”. Na dissertação, (PORTO, 2009) afirma que o desempenho mede a capacidade de um sistema

(38)

realizar trabalho ao consumir recursos e tempo, descrevendo o comportamento do sistema através de números.

Nas seções seguintes, apresentaremos dois tipos de escalabilidade, a saber: horizontal e vertical.

2.5.1

Escalabilidade Horizontal (Scale Out/In)

Acontece quando o sistema possui a capacidade de expandir ou retrair seu poder de processamento, através da adição ou remoção de novas instâncias para otimizar o desempenho na execução de uma tarefa.

Figura 13. Escalabilidade horizontal

Fonte: Parsons. (2017)

A Figura 13, demonstra a escalabilidade horizontal. Nela, é possível ver a expansão dos nós em um Data Center. Ele cria um conjunto de nós idênticos para atender a uma determinada demanda de requisições.

(39)

2.5.2

Escalabilidade Vertical (Scale Up/Down)

O conceito de escalabilidade vertical de acordo com (PARSONS, 2017) é quando um único servidor utiliza mais do que seus recursos internos para melhorar o desempenho para uma aplicação. A Figura 14 exemplifica esse conceito. Com isso, os recursos a serem adicionados para a melhoria do desempenho podem ser relacionados a componentes (hardware) do sistema computacional: Memórias de Acesso Randômico – do inglês Random Access

Memory (RAM), placas de rede, placas de vídeo, Unidade Central de

Processamento – do inglês Central Process Unity (CPU), etc. Eles podem ser idênticos aos anteriores ou simplesmente mais sofisticados, para substituir ou complementar o conjunto computacional. Esses componentes podem ser reais ou virtuais a depender da decisão arquitetural adotada pelo sistema.

Figura 14. Escalabilidade Vertical

(40)

2.6 Balanceamento de Carga

Na seção anterior falou um pouco sobre a distribuição/atribuição de carga em um determinado sistema. Perceba que a forma como estas cargas são atribuídas (baseado em alguns requisitos), pode se configurar em um problema de balanceamento de carga.

O escalonamento possui vários objetivos, não só o de balanceamento de cargas. Como indica (BRANCO, 2004 apud SHIARAZI & HURSON, 1992 et al), a literatura da área demonstra que os algoritmos de escalonamento se propõem a uma grande variedade de objetivos: compartilhamento de carga, aumento da utilização do processador, redução do tempo de resposta, redução do tempo de execução, balanceamento de cargas, entre outros.

Neste sentido, pode-se inferir que o balanceamento de carga como um tipo específico de escalonamento, ou seja, é um problema específico de escalonamento. Então, quando busca-se distribuir a carga de trabalho entre entidades de um sistema se baseando em determinados critérios, de modo que deseja-se identificar a forma ideal dessa distribuição (a ponto de tornar a carga compatível aos elementos constituintes), isso caracteriza-se em um problema de balanceamento de carga.

Em outras palavras, o problema do balanceamento é a maneira ideal de se distribuir a carga de trabalho em um sistema, obedecendo a certos critérios e definições propostas pelo problema do escalonamento. Enquanto o escalonamento especifica as possibilidades de distribuição de carga, o balanceamento escolhe dentre essas possibilidades qual é a ótima para ser aplicada em um determinado contexto.

(41)

2.6.1

Algoritmos de balanceamento

No artigo de (SARANYA,2015) intitulado como “Load Balancing Algorithms in Cloud Computing: A Review”, apresenta-se, dentre outras coisas, os benefícios do balanceamento de carga e alguns algoritmos de balanceamento.

Como benefícios, podemos citar a redundância, escalabilidade, otimização de recursos e segurança.

Existem diversos algoritmos relacionados ao balanceamento de carga de trabalho. Demonstraremos a seguir alguns deles, os quais podem ser divididos em duas partes diferentes (SARANYA, 2015, p.1): estática e dinâmica.

● Algoritmos Estáticos: Não consideram o estado atual do sistema, para tomada de decisão, quer dizer, se existe algum elemento do sistema que esteja indisponível, se a transmissão da carga de trabalho acontece de forma eficiente, etc. Os mais comuns são:

Round Robin (RR): Ele usa uma abordagem de fila circular.

Em seu primeiro ciclo de distribuição, a carga de trabalho é atribuída aos nós de forma sequencial. Do primeiro ao n-ésimo nó. Nos ciclos seguintes, todo o processo é repetido. ○ Weighted Round Robin (WRR): Este algoritmo é uma

variação do RR. Os nós envolvidos possuem pesos que os fazem receber maior ou menor número de requisições, antes de o algoritmo escolher o próximo nó da sequência. Quanto maior for o peso, maior será a quantidade de requisições que o nó recebe.

(42)

estática contendo as informações dos endereços IP de destino dos nós constituintes do cluster, para que eles recebam as requisições. O balanceador atribui as conexões aos nós do cluster, através dessa tabela.

Source Hashing (SH): Similar ao DH, sendo que faz o

balanceamento por meio do endereço IP de origem, ou seja, do IP do cliente.

● Algoritmos Dinâmicos: Consideram informações do estado atual do sistema, na tomada de decisões. Assim, o procedimento de distribuição é gerado em tempo de execução. Exemplos:

Least-Connection (LC): As conexões que chegam ao

balanceador são direcionadas ao nó com menor número de conexões. Ele é considerado um algoritmo dinâmico, porque tem que saber quantas conexões estão ativas, no momento, para cada servidor, e assim, tomar a decisão de estabelecimento de conexão com o nó apropriado.

Weighted Least-Connection (WLC): Uma variação do LC,

seguindo a ideia do WRR. O nó que possui menor porcentagem de conexões e maior peso, recebe a conexão. A razão entre a porcentagem de conexões e os pesos, faz com que o balanceador tome a decisão apropriada, para este contexto.

Locality-Based Least-Connection (LBLC): Encaminha as

requisições para o nó que possui poucas conexões. Ele efetua um roteamento através do endereço IP de destino pertencente à algum nó do cluster. Mas, se o nó estiver sobrecarregado e houver algum outro nó com metade da sua carga. A este é atribuído o endereço IP para receber a requisição.

Locality-Based Least-Connection with Replication (LBLCR):

Uma variação do LBLC, diferenciando-se deste pelo fato de mapear um subconjunto de nós do cluster, através de um

(43)

endereço IP. A requisição para esse subconjunto é direcionada ao nós com menor número de conexões. Uma vez que haja a sobrecarga de todos os nós no subconjunto, um novo nó é replicado e adicionado ao subconjunto mapeado. Os demais nós são descartados para evitar novas sobrecargas.

Shortest Expected Delay (SED): Faz o cálculo do menor

atraso esperado dos nós do cluster. Ele atribui a conexão ao nó que tiver 𝑚𝑖𝑛{𝐶𝑖

𝑈𝑖} , onde Ci corresponde ao número de

conexões ativas do i-ésimo nó e Ui , ao seu peso.

Never Queue (NQ): Atribui as conexões aos nós ociosos, uma

vez que não exista nós ociosos, o algoritmo executa um SED para efetuar a atribuição.

2.6.2

Tipos de Balanceamento

Como já discutido, o balanceamento de carga pode ser realizado em diversos níveis da infraestrutura de Tecnologia da Informação (TI).

Em se tratando de sistemas distribuídos, basicamente existem dois tipos de balanceamento de carga de trabalho, o que referencia a camada 7 e o que referencia a camada 4. No primeiro, a tomada de decisão para o balanceamento é voltada à informações do cliente ou servidor com base no conteúdo das requisições de um dado protocolo, por exemplo HTTP. Este tipo também é conhecido como balanceamento de carga de aplicação. No segundo, a tomada de decisão para a distribuição do tráfego baseia-se nas informações da camada 4. Também conhecido como balanceamento de carga de rede. Eles serão relatados mais adiante

2.6.3

Balanceadores de cargas

São componentes de um sistema que possuem a capacidade de gerenciar uma carga de trabalho, tendo a função de distribuí-la

(44)

uniformemente. Conforme (Samal et al., 2013, p. 416) o objetivo do balanceamento de carga é melhorar o desempenho por balancear a carga entre vários recursos (links de rede, unidades de processamento central, drives de discos etc.). A Figura 15 mostra um cenário de rede onde é utilizado um balanceador de carga.

Como a referência diz, este balanceamento pode ser realizado em diversos elementos computacionais, tais como: discos rígidos, clusters de computadores, CPU’s, etc; que podem ser entendidos como os recursos que recebem a carga de trabalho gerenciada pelos balanceadores.

No contexto deste trabalho, o foco é a distribuição de carga considerando o tráfego de pacotes em uma rede de dispositivos, de modo que os componentes do sistema descrito acima são roteadores, switches,

workstations, dentre outros. A capacidade dos balanceadores de carga é

advinda de funções, métodos ou módulos que estão inseridos dentro do kernel desses componentes. A implementação dessas funções envolve técnicas que permitem aos balanceadores distribuírem, de maneira proporcional, o fluxo de informações que passam por eles.

O balanceamento de carga deve obedecer a alguma política de escalonamento. Como descrito na seção 2.5.

(45)

Figura 15. Balanceador de carga

(46)

3 Trabalhos Relacionados

Este capítulo apresenta os principais projetos e soluções que embasaram o desenvolvimento do sistema de balanceamento de carga proposto neste trabalho. São apresentados alguns serviços de balanceamento de carga, com destaque para o Microsoft Azure, Amazon AWS, HAProxy e o do

Linux Virtual Server (LVS).

3.1 Microsoft Azure

A plataforma de computação em nuvem da Microsoft, a Microsoft Azure, abrange uma gama de serviços de nuvem com ferramentas que dão suporte aos desenvolvedores. Essas ferramentas se integram aos serviços para auxiliar a comunidade de TI na construção de aplicações para nuvem. Seja mobile ou outros tipos de soluções em software.

Um dos serviços da Azure é o balanceador de carga básico, que consiste em um balanceador da camada de transporte ou camada 4 (TCP/UDP) do modelo OSI. O balanceador em questão possui os seguintes recursos: distribuição baseada em hash, encaminhamento de porta, reconfiguração automática, monitoramento do serviço e NAT de Origem. Nós podemos visualizar isso na Figura 16.

(47)

Figura 16. Modelo do balanceador Microsoft Azure

Fonte: Dwivedi et all. (2017)

Como o próprio nome já diz, o recurso de distribuição baseada em hash usa um algoritmo que distribui a carga entre as instâncias (Máquinas Virtuais internas) de acordo com um código hash, segundo Dwivedi (2017), gerado a partir de uma 5-tupla envolvendo o endereço IP de origem, porta de origem, endereço IP de destino, porta de destino e protocolo. Ele faz isso para manter a sessão do cliente, seja ela TCP ou UDP. A cada nova requisição do cliente (pelo fato de ser gerada uma nova porta de origem), um novo hash é produzido, direcionando os pedidos de conexão para uma nova instância.

No encaminhamento de porta, é feito um mapeamento de portas públicas do ponto de extremidade externo (ou balanceador de carga) para o interno (ou instância de máquina virtual). Neste caso, o tráfego é redirecionado de acordo com esse mapeamento, por exemplo: da porta 80 para 81, 22 para 2222, etc. Assim, pode-se configurar uma faixa de portas internas para uma externa. A reconfiguração das instâncias com o ponto de extremidade externo é realizada automaticamente, mantendo a escalabilidade do sistema.

(48)

.

3.2 Amazon Web Services (AWS)

A Amazon Inc. é uma empresa norte americana de e-commerce e

cloud-computing fundada por Jeff Bezos em 5 de julho de 1994. Hoje ela possui

diversos serviços e plataformas para inúmeras necessidades. Uma delas é a plataforma de cloud-computing AWS. Há dois conceitos que são relacionados a organização da estrutura dessa plataforma. Um deles é a Região, que nada mais é do que o lugar onde os data centers estão. O outro é a Zona de Disponibilidade que corresponde a cada data center, como apresenta a Figura 17.

A AWS abriga um serviço de balanceamento de carga chamado Elastic

Load Balancing. De acordo com a documentação da AWS, ele distribui o

tráfego de aplicação entre instâncias da Nuvem de Computação Elastica - do inglês Elastic Compute Cloud (EC2) de diversas zonas de disponibilidade. Essa forma de distribuição ou balanceamento é denominada como balanceamento clássico, mas o Elastic também possui suporte aos balanceamentos de rede e aplicação.

(49)

Figura 17. Modelo do balanceador AWS

Fonte: (2017, p. 1)

A documentação ainda explica que o serviço Elastic é capaz de fazer verificação de sanidade entre as instâncias da zona de disponibilidade e efetua escalabilidade automática delas, de acordo com o fluxo de requisições da aplicação.

3.3 Nginx

Projeto open source que pode ser implantado em diversas plataformas de software. Ele foi idealizado por Igor Sysoev e está executando em muitos empresas, como: Yandex, Mail.Ru, VK, Rambler, Dropbox, Netflix, Wordpress.com, FastMail.FM, entre outras.

A plataforma NGINX possui alguns produtos tais como: NGINX Plus,

NGINX Controller, NGINX Unit, NGINX Web Application Firewall, NGINX Amplify.

Segundo a documentação do NGINX, o produto NGINX Plus é um

(50)

que oferece funcionalidades além das disponíveis com o projeto NGINX, a saber: sessão de persistência, configuração via Interface de Programação de Aplicações - do inglês Application Programming Interface (API) e verificação de sanidade. A Figura 18 demonstra um modelo do balanceador NGINX.

Figura 18. Modelo do balanceador NGINX

Fonte: (2017)

O NGINX implementa os algoritmos RR, LC, ip_hash (refere-se ao balanceamento da camada 4, considerando apenas o endereço IP), Generic

hash (refere-se ao balanceamento da camada 4 e 7) e o least_time (disponível

apenas no NGINX Plus) que direciona as requisições para o nó com menor latência média e menor número de conexões ativas. O least_time determina dois parâmetros para o cálculo da menor latência média: header (tempo de recebimento do primeiro byte do servidor) e last_byte (tempo para receber a resposta completa do servidor).

3.4 HAProxy

Conforme sua documentação

(51)

designate the executable program, software package or a process, though both are commonly used for both purposes, and is pronounced H-A-Proxy. Very early it used to stand for "high availability proxy" and the name was written in two separate words, though by now it means nothing else than "HAProxy".

A característica de alta disponibilidade citada em sua definição não é a única, o HAProxy também possui chaveamento de conteúdo, monitoramento, balanceamento de carga, dentre outras. Em relação ao balanceamento de carga, os mais comuns suportados pelo produto são o RR, LC, source (similar ao DH), uri (para cache HTTP; faz balanceamento na camada 7) e hdr (faz balanceamento na camada 7).

3.5 Linux Virtual Server (LVS)

Nascido em 1988, o projeto open source Linux Virtual Server (LVS) teve como objetivo a construção de servidores de alta performace e disponibilidade para sistemas baseados em Linux.

O LVS possui alguns componentes em seu framework, dos quais se destacam três. O primeiro deles, chamado de Servidor Virtual de IP – do inglês

IP Virtual Server (IPVS), é um software de balanceamento de carga que é

inserido dentro do kernel do Linux. Assim como o IPVS, o KTCPVS também é inserido dentro do kernel e faz o balanceamento de carga a nível de aplicação. E o último, é denominado de Cluster Management usado para monitoramento e administração dos computadores que pertencem ao cluster. A Figura 19 mostra uma visão geral do framework.

(52)

Figura 19. Framework LVS

Fonte: Zhang. (2004)

Entre os objetivos desse framework estão a garantia de fornecer escalabilidade, confiabilidade e capacidade de manutenção, usando uma tecnologia de clustering. É importante apresentar alguns conceitos acerca do

LVS, como: Servidores Reais – do inglês Real Server (servidor que fornece o

serviço), Farm (conjunto de Real Servers que compõem o cluster), IP virtual (VIP), usado para o acesso das requisições do cliente, IP dos Real Servers (RIP) e Probe (Operação de monitoramento que verifica a sanidade dos componentes).

Existem três modos de tratamento de requisições usados no LVS. I. LVS VIA NAT

A técnica de NAT, como sabemos, consiste na tradução do endereço de rede, como a sigla auto se define. No método LVS via NAT, mostrado na Figura 20, acontece o mesmo. O balanceador de carga, que possui o IP Virtual, recebe as requisições do cliente, traduz o endereço de IP de destino para um dos endereços IP dos servidores reais e estes respondem ao balanceador, que

(53)

dessa vez, traduz o endereço de IP de origem como sendo o seu e, assim, responde às requisições dos clientes. É importante destacar que nesse método acontece a reescrita do pacote IP duas vezes. E o pacote passa pelo balanceador duas vezes para uma única requisição do cliente, isso requer um aumento no consumo de recursos computacionais, diferentemente dos métodos seguintes.

Figura 20. Método LVS via NAT

Fonte: Zhang. (2004, p. 3)

II. LVS VIA IP Tunneling

Neste método, realiza-se um túnel entre os servidores reais e o balanceador. Ele pode ser visto na Figura 21. Este túnel pode ser implementado em uma rede local ou não.

(54)

Toda requisição que passa pelo balanceador e é atribuída à algum serviço (do sistema), é encaminhada aos servidores de aplicação (através do encapsulamento do pacote IP e de acordo com a tabela de rotas do balanceador) que respondem à requisição diretamente ao cliente.

Figura 21. Método LVS via IP Tunneling

Fonte: Zhang. (2016, p. 4)

Perceba que há a manipulação do pacote, quando ele é encaminhado pelo balanceador ao realizar o encapsulamento. Isso retarda um pouco o processo, mas temos um ganho melhor de eficiência se comparado ao LVS Via

NAT.

III. LVS VIA Direct Routing

Similar ao LVS Via IP Tunneling, no LVS Via Direct Routing, exibido na Figura 22, as respostas às requisições (vindas do cliente e direcionadas pelo

(55)

servidor ao cluster) são feitas diretamente pelos servidores reais. Porém, temos aqui duas ressalvas. Pelo fato do RIP ser igual ao VIP, o Protocolo de Resolução de Endereços – do inglês Address Resolution Protocol (ARP) - deve estar desabilitado, tanto no cluster quanto no balanceador. O cluster de servidores tem que estar na mesma rede local que a do balanceador, pois no direcionamento feito pelo balanceador, há a reescrita do endereço MAC de destino (endereço do servidor real). Essa última característica diminui a sobrecarga do processo, uma vez que a reescrita do pacote acontece na camada de enlace.

Figura 22. Método LVS via Direct Routing

Fonte: Zhang (2004, p. 4)

O LVS implementa os seguintes algoritmos listados na seção 2.6.2: RR,

(56)

4 Implementação

de

um

Balanceador de Carga para uma

Aplicação Qualquer

Neste capítulo será apresentado de maneira genérica, a ideia geral de um balanceador de carga, que efetua o balanceamento da carga de trabalho para um cluster de aplicações quaisquer. Exibirá um esquema matemático para o entendimento da distribuição da carga e um modelo, enfatizando o funcionamento do balanceador.

4.1 Esquema Matemático

O intuito da apresentação desse esquema é descrever idealmente o funcionamento de um balanceador de carga genérico, sendo que, a disposição de seus componentes é baseada no escopo desse trabalho.

Nos objetivos citados neste documento, construímos a hipótese de que ao distribuirmos a carga de trabalho entre os nós, aumentamos o desempenho do processamento de cada carga, diminuindo a sobrecarga nos nós do cluster. Espera-se que o mesmo ocorra quando aumentarmos o número de nós. Para provarmos essa hipótese devemos nos aproximar do ideal. No capítulo 6 são apresentados os experimentos realizados a fim de validar essa ideia.

Nós já norteamos um pouco a ideia do trabalho, falando a respeito do “balanceador”, mas na verdade, o sistema de balanceamento discutido aqui consiste, principalmente, de dois balanceadores de carga. Um deles faz a interface entre a rede externa e o cluster de aplicação; o outro é o intermediário entre o cluster e a rede interna. Para visualizarmos melhor o fluxo dentre os balanceadores e o conjunto de aplicações, tomaremos como

(57)

referência o modelo de escalonamento em sistemas distribuídos proposto por (LOPES & MANASCÉ, 2015).

Como já apresentado, este modelo destaca três componentes básicos: carga de trabalho, recursos e requisitos. Sabemos que a carga de trabalho é responsável por consumir os recursos do sistema. Com isso, podemos definir a carga de trabalho como um conjunto do qual seus elementos podem ser associados à recursos, como tarefas a serem executadas por eles. Assim, considerando a Figura 23

Figura 23. Esquema matemático do balanceador de carga

Fonte: elaborado pelo autor

𝛽

0 e

𝛽

1 representam os balanceadores de carga,

𝛬

representa a carga

de trabalho total (ou o conjunto total de conexões) a ser distribuída entre os recursos, que são representados através dos

𝜌

, podendo haver r destes. Cada

𝜌

possui um

𝜆

que indica a carga de trabalho a ser processada (ou

𝜆 ⊆ 𝛬

). De maneira ideal, as

𝛬

são iguais, as

𝜆

, também e os

𝜌

são idênticos entre si. Não há perda de carga de trabalho. As setas bidirecionais indicam, abstratamente, os links entre os balanceadores e os recursos. A distribuição da

𝛬

se dá por meio de um valor h obtido de uma função hash genérica ideal que recebe como parâmetro a

𝛬

. No esquema, r e k pertencem ao conjunto dos naturais sem o zero. É importante salientar que r e k são iguais. O valor h

(58)

também pertence aos naturais e é compreendido entre 1 <= h <= d, seja d = r

= k.

Para a ideia apresentada, é óbvio que

Perceba que, como

𝜆

i é subconjunto de

𝛬

, ele não se refere à i-ésima

conexão e sim ao i-ésimo conjunto de conexões contidas em

𝛬

.

Os balanceadores

𝛽

são compostos das funções hash que, ao receber o conjunto

𝛬

, faz um cálculo com os elementos desse conjunto para a obtenção de h e , a partir daí, atribuir a

𝜆

h ao recurso

𝜌

h apropriado.

Como foi falado, este esquema possui dois balanceadores. Claro que não é obrigado se ter os dois para se efetuar o balanceamento, porém isto é apenas uma característica peculiar. No caso, os

𝛽

devem produzir um mesmo h para garantir a transmissão do conjunto de conexões por um

𝜌

único.

4.2 Arquitetura

Na seção 3.1 foi apresentado o funcionamento do fluxo de atribuição de tarefas à recursos do sistema. Aproximando-se ainda mais do contexto desse trabalho.

Nesta seção será apresentado a ideia geral da arquitetura e o seu funcionamento, analisando o fluxo das requisições feitas por componentes de

(59)

uma rede de dispositivos (usuários, clientes, servidores, datacenter’s, aplicações) que “atravessam” o sistema de balanceamento em questão.

4.2.1

Ideia Geral

Para uma maior clareza da arquitetura observe a Figura 24. Nela, é possível ver duas setas bidirecionais. A primeira delas (mais à esquerda) representa as requisições dos serviços ou clientes externos, que passam pela infraestrutura da internet até chegar ao balanceador de carga mais externo. A segunda, demonstra de maneira análoga o fluxo de requisições dos clientes internos, passando pela infraestrutura interna da rede e chegando ao sistema de balanceamento. A parte central da figura corresponde ao sistema, propriamente dito, composto dos dois balanceadores - já discutidos – conectados aos servidores de aplicação do cluster. É importante enfatizar que as aplicações envolvidas podem ser de quaisquer naturezas (servidores IDS, servidores de email, firewalls, etc).

Figura 24. Arquitetura proposta do trabalho

Referências

Documentos relacionados

A proposta aqui apresentada prevê uma metodologia de determinação da capacidade de carga de visitação turística para as cavernas da região de Bulhas D’Água

Agrupa as palavras em agudas, graves e esdrúxulas, tendo em conta a posição da sílaba tónica.. Esdrúxulas

8- Bruno não percebeu (verbo perceber, no Pretérito Perfeito do Indicativo) o que ela queria (verbo querer, no Pretérito Imperfeito do Indicativo) dizer e, por isso, fez

A Sementinha dormia muito descansada com as suas filhas. Ela aguardava a sua longa viagem pelo mundo. Sempre quisera viajar como um bando de andorinhas. No

5- Bruno não percebeu (verbo perceber, no Pretérito Perfeito do Indicativo) o que ela queria (verbo querer, no Pretérito Imperfeito do Indicativo) dizer e, por isso, fez

10. A Joana disse-me que, no dia seguinte, iria a casa da Beatriz buscar os livros de Português, porque, no dia anterior, lhe tinham dito que teria teste e ainda não tinha estudado

• The definition of the concept of the project’s area of indirect influence should consider the area affected by changes in economic, social and environmental dynamics induced

de uma instituição de ensino público federal e sua principal contribuição, tanto na perspectiva prática quanto teórica, reside na análise de aspectos da