• Nenhum resultado encontrado

4.4 Recuperação do estado contido em um checkpoint

5.1.3 Balanceamento de carga em DHTs

Um problema importante relativo às tabelas de espalhamento distribuídas (DHTs) é que, quando os identificadores dos nós são distribuídos de maneira aleatória, nós diferentes ficam responsáveis por faixas de identificadores de tamanhos diferentes. Dado um número m de identificadores e n de nós no sistema, é possível mostrar que com alta probabilidade existirão nós responsáveis por uma faixa de identificadores da ordem de log n vezes o tamanho médio da faixa alocada a cada nó [67].

A situação é agravada no caso de nós heterogêneos, já que o tamanho da faixa alocada a cada nó não tem nenhuma relação com a sua capacidade. Aqui estamos supondo que é possível definir uma métrica a partir da qual podemos estimar a capacidade de um nó para atender a requisições provenientes do sistema peer-to-peer. Por exemplo, em um sistema de armazenamento distribuído, a capacidade pode ser a largura de banda da rede que liga o nó ao restante do sistema ou quantidade de espaço disponível para armazenamento em disco. O resultado é que alguns nós da rede acabam sobrecarregados enquanto outros permanecem ociosos pela maior parte do tempo.

Normalmente, supomos que os identificadores dos dados são gerados de forma aleatória e uniforme, utilizando, por exemplo, uma função de espalhamento segura como SHA-1. Sob esta suposição, o ba- lanceamento de carga seria equivalente a balancear o espaço de endereços. Mas ainda assim é possível que exista uma assimetria nas requisições a determinados identificadores. Por exemplo, um arquivo de um sistema de arquivos distribuídos pode ser particularmente popular, gerando uma sobrecarga extra em um servidor. Além disso, as taxas de acesso a cada arquivo tendem a variar dinamicamente, de modo que, durante a evolução do sistema, diferentes servidores ficarão sobrecarregados. Finalmente, a própria capacidade de um nó pode ser alterada com o passar do tempo. Esta volatilidade do sistema nos leva a outro conceito importante, que é o de balanceamento de carga dinâmico, onde a faixa de identifica- dores alocada para cada nó é alterada dinamicamente durante a execução do sistema. Deste modo, o sistema compensa as variações na carga ou capacidade de um nó que ocorrem durante o tempo de vida do sistema.

Técnicas para o balanceamento de carga

A abordagem mais utilizada para balancear a faixa de identificadores atribuída a cada nó é utilizar o conceito de servidores virtuais [67]. Neste caso, cada nó do sistema fica responsável pelas faixas de identificadores alocadas a um determinado número de servidores virtuais. Uma abordagem bastante simples é instanciar O(log n) servidores virtuais em cada nó, onde n é o número de nós na rede [35, 67, 118]. Deste modo, os nós passariam a ser responsáveis por faixas de endereços de aproximadamente o mesmo tamanho. Esta abordagem é bastante simples, mas tem a desvantagem de necessitar que cada nó armazene informações sobre log n nós ao invés de apenas um, além do tráfego gerado na rede para manter estas tabelas adicionais. No extremo oposto, existe a possibilidade de permitir que cada nó escolha e instancie exatamente um de log n servidores virtuais alocados para o nó [68]. Neste caso não

5.1 Sistemas peer-to-peer 73 existe a sobrecarga causada pelo grande número de servidores virtuais.

Mas, ambas as abordagens acima citadas não tratam da heterogeneidade dos nós e não permitem a adaptação a mudanças dinâmicas na carga dos nós. Para tratar o problema da heterogeneidade, podemos permitir que cada nó escolha quais servidores virtuais instanciar de acordo com sua capacidade. Mas, neste caso, cada nó precisa comparar a sua capacidade com relação às de seus vizinhos e precisa de uma estimativa do número de nós presentes no sistema. Se servidores virtuais não fossem utilizados, o número de nós no sistema poderia ser estimado a partir do tamanho da faixa de identificadores coberta pelos nós vizinhos a um determinado nó. Esta estimativa é possível se supormos que os identificadores são fornecidos de forma aleatória. Mas se cada nó puder instanciar diferentes números de servidores virtuais baseados em sua capacidade, esta abordagem de estimativa local passa a ser inviável. Neste caso, com a utilização de servidores virtuais, pode ser difícil estimar o número de nós no sistema.

Uma maneira de solucionar este problema é utilizar o balanceamento de carga dinâmico, de modo que o sistema dinamicamente se ajuste de acordo com sua evolução. Para tal, podemos permitir que nós com alta utilização no sistema transfiram servidores virtuais para nós com baixa utilização. Podemos dizer que um nó está com alta utilização se o uso dos recursos do nó estiver acima de um determinado limiar e com baixa utilização se o uso dos recursos estiver abaixo deste mesmo limiar. Diversas estratégias podem ser utilizadas para selecionar quais nós devem trocar servidores virtuais [54, 103]. Uma maneira bastante simples é selecionar pares de nós aleatoriamente e realizar a troca de servidores virtuais se um nó estiver com alta e o outro com baixa utilização. Outra possibilidade é utilizar diretórios distribuídos que armazenam informações sobre a utilização dos nós do sistema e aos quais cada nó periodicamente envia seu estado. Nós com alta utilização podem procurar no diretório por nós com baixa utilização para o qual possam transferir servidores virtuais.

Uma abordagem diferente é permitir que os nós transfiram parte da sua faixa de identificadores para seus vizinhos [68, 144]. Esta distribuição de faixas de identificadores entre vizinhos pode levar em conta a heterogeneidade dos nós, de modo a atribuir a cada nó uma faixa de identificadores proporcional à sua capacidade. Deste modo, é possível fazer o balanceamento dinâmico de carga em redes heterogêneas utilizando apenas informação local sobre os vizinhos dos nós.

Um fator importante a se considerar é que mudanças nas faixas de identificadores alocadas a cada nó normalmente requerem que dados sejam transferidos entre estes nós. No caso de aplicações de ar- mazenamento de dados, pode ser necessário transferir grandes quantidades de dados. Isto porque os dados estão associados a um identificador e podem precisar ser transferidos caso o nó responsável por aquele identificador seja alterado. Nestes casos, a utilização de informação de proximidade entre nós pode influenciar favoravelmente o desempenho do algoritmo, uma vez que dados são transferidos por distâncias menores. Foram publicados alguns trabalhos que tratam da proximidade entre nós [112, 147]. Uma maneira de determinar distâncias entre nós de um sistema é utilizar o conceito de aglomeração por pontos de referência (landmark clustering) [112, 147]. Neste caso, cada nó determina sua distância a um determinado número de pontos de referência, que podem ser nós do próprio sistema, construindo um ve-

tor contendo estas distâncias. Se utilizarmos um número suficientemente grande de pontos de referência, podemos inferir que nós com vetores de distâncias similares estão localizados em pontos geográficos próximos.