A melhor maneira de balancear a carga em vários servidores de arquivos estáticos, mesmo para uma distribuição de largura de banda?

11

Primeiro, vou explicar minha situação para você. Estou executando um site bastante popular como um projeto paralelo, então não posso investir muito dinheiro nisso. Atualmente, tenho apenas um servidor com o HAProxy na frente enviando solicitações normais para o Apache e todas as solicitações de arquivos estáticos para o Lighttpd. Isso está funcionando muito bem, porque todas as solicitações php e post são manipuladas pelo Apache, enquanto todas as imagens são enviadas para o Lighttpd mais rápido (o site é principalmente imagens, então isso é realmente importante). Seria bom não ter que configurar um subdomínio para servir as imagens, porque as URLs curtas também são realmente importantes, portanto, meu motivo para usar o HAProxy.

Eu encontrei um provedor de hospedagem que oferece largura de banda sem bitrate bastante barata que eu tenho usado, o problema surge quando eu começo a empurrar a largura de banda que a placa de rede de 100mbs aguenta, precisando assim de um segundo servidor. / p>

Eu coloquei muita atenção nas minhas opções, então vou explicar cada uma para você. Espero que você possa fornecer algumas dicas sobre qual é a melhor opção para mim, ou talvez haja outra opção por aí que eu não tenha pensado ainda.

Requisitos:

  • Até mesmo a distribuição de largura de banda é obrigatória. Eu tenho um servidor muito poderoso, então aumentar a escala não é uma opção. Eu preciso expandir para ganhar mais largura de banda.

  • URLs curtos. Eu realmente não quero configurar um subdomínio, como img.example.com, para servir minhas imagens. example.com/image.jpg é como está agora e como eu realmente gostaria que ficasse. Mas se não há outra maneira, então eu entendo.

  • O servidor mais próximo que lida com o pedido seria muito bom, mas não é obrigatório. Algo para manter em mente.

HAProxy para loadbalance:

  • Seria muito fácil de fazer, já que eu já estou usando o HAProxy. No entanto, acho que o problema surge ao distribuir a largura de banda. Eu posso estar errado nisso, mas o HAProxy não envia a solicitação para um servidor onde o servidor a processa e a envia de volta por meio do HAProxy para o cliente? Assim, todo o tráfego volta pelo balanceador de carga, fazendo com que ele use o máximo de largura de banda que todos os servidores combinados.

DNS Round Robin:

  • Essa pode ser minha melhor opção. Apenas replique o site em vários servidores e faça o que eu estou fazendo agora. A desvantagem é que, se um servidor ficar inativo, os clientes ainda serão enviados para ele. Eu também precisaria replicar o site nos vários servidores. Eu estava meio que esperando que eu pudesse ter um servidor principal que lida com tudo, exceto arquivos estáticos, e depois ter alguns servidores de arquivos estáticos. Eu também li que isso era uma espécie de 'balanceamento de carga do pobre', e seria bom ter algo um pouco mais sofisticado.

Retorno direto ao servidor:

  • Parece muito complicado, mas pode ser uma boa opção. Eu ainda seria capaz de enviar determinados URLs para determinados servidores? Como agora com o HAProxy, cada URL que termina na extensão de arquivo correta é enviada para o Lighttpd, enquanto outras extensões são enviadas para o Apache. Então eu precisaria de algo similar. Como, todas as solicitações php são manipuladas pelo mesmo servidor que está executando o software de balanceamento, enquanto todas as solicitações jpg são enviadas para vários servidores.

Idealmente, se o HAProxy suportasse o Direct Server Return, meu problema seria resolvido. Eu também não quero usar um CDN, porque eles são realmente caros, e este é apenas um projeto paralelo, afinal.

Você entende meu problema? Deixe-me saber se eu não expliquei algo certo ou se você precisa de mais informações.

    
por Alan 27.08.2009 / 16:50

6 respostas

3

Faça uma imagem do seu ciclo de solicitação / resposta para o aplicativo e isole o gargalo. Você está certo de que um único proxy que distribui carga para muitos servidores de aplicativos exigirá a largura de banda agregada de todos os servidores de aplicativos. A solução clássica é o DNS RR. Google, Yahoo e Amazon usam essa técnica com um curto TTL. Eu fiz alguma investigação há algum tempo e documentou minhas descobertas .

Outra solução é usar uma solução de balanceamento de carga corporativa sofisticada usando endereçamento IP virtual para balancear solicitações entre vários servidores de aplicativos com endereços IP reais. Eu trabalhei com produtos Netscaler e Stonesoft. Ambos têm bom desempenho, mas têm terríveis idiossincrasias e são bastante complexos.

    
por 27.08.2009 / 18:56
3

Algumas respostas:

  • Sim, todo o tráfego passa pelo HAProxy, pois funciona como um proxy de nível HTTP. Isso será o mesmo, mesmo se o HAProxy estiver instalado em um servidor separado, que salve vários servidores back-end. Portanto, se o provedor de hospedagem fornecer apenas 100 MB de portas de rede e você já estiver usando 100 MB, você terá um problema.
  • Em relação ao domínio, o ideal seria veicular imagens de um domínio diferente do seu aplicativo da Web - não um subdomínio, um diferente, para que os cookies não sejam enviados nas solicitações de imagens. Consulte o trabalho original de Steve Souders ou a implementação aqui no Stack Overflow . Se as URLs curtas são muito importantes para você, talvez o melhor seja mover a webapp do URL principal, ou seja, mover o aplicativo de gerenciamento de arquivos para login.sitename.com?

Você precisa de autenticação nas solicitações de imagens? Se não, que tal usar algo como o Amazon S3? É massivamente escalável e o custo de transferência de dados é bastante barato. Nesse caso, usaria algo como i.sitename.com como CNAME de DNS para o nome de host do bucket do Amazon S3, veja os documentos da Amazons . AFAIK você não pode ter o nome de domínio raiz (sitename.com) como um CNAME, então você deve usar um subdomínio como i.sitename.com para isso.

Você também pode transformar suas imagens em vários servidores. você cria uma estrutura DNS como login.sitename.com e a.sitename.com; b.sitename.com; c.sitename.com et cetera. O "a" e B." servidores etc apenas contêm um sistema de arquivos com imagens e um servidor HTTP leve (você já está usando o Lighttpd, então continue usando isso. Para um projeto futuro, eu proporia olhar nginx como um substituto melhor.) Quando um usuário carrega uma imagem, você cria um hash de um identificador único, talvez seu nome de usuário, talvez o nome do arquivo ou uma combinação de vários identificadores . A partir desse hash, você determina em qual servidor armazenar a imagem.

Editar Eu deveria ter visto que hashing já foi discutido. Essencialmente, o que estou propondo aqui é usar o hash no nome do host também, para distribuir o tráfego de rede uniformemente em vários hosts.

Eu não sei quão barato você precisa que isso seja - mas quando você está empurrando 100MB de tráfego de rede, então "barato e bom" rapidamente se torna uma ilusão. Talvez você devesse procurar primeiro um bom modelo de negócios, algo que forneça receitas recorrentes e depois implemente a tecnologia apropriada depois disso?

    
por 02.09.2009 / 01:29
1

Eu suponho que o HAProxy está no mesmo servidor que seus outros aplicativos? Você poderia dividir o HAProxy em outro sistema para executar as solicitações e fazer com que ele enviasse solicitações normais para um servidor e solicitações de imagens para outro servidor. A questão é que todas as solicitações ainda estão indo para uma caixa, e se você está saturando sua largura de banda, isso pode não ajudar muito.

Você diz que os URLs curtos são importantes. Por quê? É realmente um grande negócio mudar as imagens de "example.com" para "i.example.com"? Você pode definir "i" para seu próprio IP em seu próprio servidor com o Lighttpd e ignorar totalmente o HAProxy, resolvendo seu problema de rendimento. Você também obteria o benefício do navegador da web, permitindo que mais solicitações sejam abertas de uma só vez, uma vez que elas seriam consideradas nomes de domínio diferentes e poderiam abrir mais conexões simultâneas. Se o único servidor "i" estivesse saturado, você poderia empregar round-robin de DNS para adicionar outro. Espero que, nessa altura, esteja a gerar receita suficiente para implementar uma solução melhor.

    
por 27.08.2009 / 16:59
1

O seu provedor de hospedagem oferece serviços de balanceamento de carga? Eu acho que é a melhor solução.

Outra maneira de fazer isso, mas precisa ser testada, é reescrever (em lighty ou apache) os pedidos. Por exemplo: example.com/file.html permanece no apache e example.com/image.jpg redireciona para i.example.com/image.jpg. Todas as solicitações serão gerenciadas através do apache, mas as respostas (upstream bandwidth) estão indo para o servidor lighttpd. O domínio é transparente para o usuário. Ainda assim você precisa testar se o apache pode lidar com todas as solicitações ou talvez deixar o lighttpd fazer esse trabalho.

Você está certo que todos os dados passam pelo HAProxy, então você não pode (tanto quanto eu sei) direcionar o retorno do servidor com ele.

UPDATE

Examinando documentação do HAproxy , encontrei o parâmetro "redir". Não sei se pode funcionar como o reescrito do apache, mas pode ser útil. A documentação diz:

Main use consists in increasing bandwidth for static servers by having the clients directly connect to them.

Talvez funcione para o seu caso.

    
por 27.08.2009 / 17:37
1

Suponho que, com qualquer conjunto considerável de imagens, você não está armazenando as imagens com base no nome do arquivo original, pois ocorreria rapidamente conflitos de nomes.

Muitos aplicativos que lidam com esses tipos de problemas usam o hash do arquivo e uma estrutura de diretório baseada nesse hash. A estrutura do diretório se parece com o seguinte, onde o caminho do diretório são os dois primeiros caracteres do hash, e o segundo nível é o próximo dos dois caracteres no hash.

/image root/AA/AA/images  
/image root/AA/AB/images

O benefício aqui é que os hashes mantêm a distribuição de arquivos bastante uniforme e fornece um namespace que é fácil de dividir em vários servidores. Basicamente, você serve porções do espaço de hash de diferentes servidores e, à medida que escala, você pode subdividir isso mais conforme necessário.

A desvantagem é que os hashes não são perfeitos e podem haver colisões. Não tenho certeza de como isso é tratado. Então, isso pode exigir um pouco de pesquisa da sua parte. Eu imagino que uma regra de reescrita no proxy deve ser capaz de fazer um hash dizer A3A8BBC83261.jpg e reescrevê-la para link . Você pode não considerar isso como uma URL curta.

    
por 27.08.2009 / 18:31
0

Em seu post, você mencionou que sentiu que o DNS round robbin poderia ser sua melhor opção, mas estava preocupado com a falha de um único servidor ...

Se for esse o caso, dê uma olhada no Simple Failover da JH Software. Eu usei isso no passado e funciona muito bem.

link

Basicamente, ele monitora seus servidores e, quando ele vê um deles, rapidamente reescreve o DNS para tirar o servidor morto da rotação.

Aqui está um trecho do site deles:

Simple Failover continuously monitors your servers to find out which are up and which are down, and then it dynamically updates your DNS records accordingly so that your domain name always points to a functional server.

It works with web-servers (HTTP), mail-servers (SMTP, IMAP, POP3), FTP-servers, and practically any other TCP/IP based server type.

Como mencionado anteriormente, usei-o no passado para sites e servidores de e-mail. Ele se saiu razoavelmente bem. O failover foi muito rápido na maioria dos casos (adivinhando 2-5min) e eu diria que quase todos falharam em menos de 15 minutos.

Não necessariamente PERFEITA ... mas definitivamente rápido e fácil.

NOTA: Este é um produto do Windows. Eu não tenho certeza se eles têm uma versão linux ou não, mas você pode falhar em qualquer servidor que você goste desde o seu DNS.

No nosso caso, nós apenas lançamos em uma máquina XP, pedimos que a máquina fosse reinicializada uma vez por noite e funcionou bem por anos.

    
por 27.08.2009 / 17:21