A melhor maneira de carregar o equilíbrio entre vários servidores de arquivos estáticos, mesmo para uma distribuição de largura de banda?


12

Primeiro, vou explicar minha situação para você. Estou executando um site bastante popular como um projeto paralelo, então não posso realmente investir uma tonelada de dinheiro nele. Atualmente, tenho apenas um servidor com 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 de php e post são tratadas pelo Apache, enquanto todas as imagens são enviadas para o Lighttpd mais rápido (o site é basicamente imagens, por isso é realmente importante). Seria bom não ter que configurar um subdomínio para veicular as imagens, porque URLs curtos também são realmente importantes, portanto, minha razão para usar o HAProxy.

Eu encontrei um provedor de hospedagem que oferece largura de banda não-medida bastante barata que eu estou usando, o problema surge quando eu começo a fornecer tanta largura de banda quanto a placa de rede de 100mbs pode suportar, necessitando de um segundo servidor.

Eu pensei muito 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 ainda não tenha pensado.

Requisitos:

  • Mesmo a distribuição da largura de banda é uma obrigação. Eu tenho um servidor bastante poderoso, então a ampliação não é uma opção. Eu preciso expandir para ganhar mais largura de banda.

  • URLs curtos. Realmente não costumo configurar um subdomínio, como img.example.com, para exibir minhas imagens. example.com/image.jpg é como é agora e como eu realmente gostaria que ficasse. Mas se não houver outra maneira, então eu entendo.

  • O servidor mais próximo que lida com a solicitação seria muito bom, mas não obrigatório. Algo a ter em mente.

HAProxy para balancear carga:

  • Seria muito fácil, pois já estou usando o HAProxy. No entanto, acho que o problema surge ao distribuir largura de banda. Posso estar errado nisso, mas o HAProxy não envia a solicitação para um servidor em que o servidor as processa e depois a envia de volta através do HAProxy para o cliente? Portanto, todo o tráfego volta pelo balanceador de carga, fazendo com que ele use tanta largura de banda quanto todos os servidores combinados.

Robin redondo de DNS:

  • Esta pode ser a minha melhor opção. Apenas replique o site em vários servidores e faça o que estou fazendo agora. A desvantagem é que, se um servidor cair, os clientes ainda serão enviados para ele. Eu também precisaria replicar o site nos vários servidores. Eu esperava que pudesse ter um servidor principal que lida com tudo, exceto arquivos estáticos, e depois ter alguns servidores de arquivos estáticos. Também li que esse era um tipo de 'balanceamento de carga do pobre homem' e seria bom ter algo um pouco mais sofisticado.

Retorno direto do servidor:

  • Parece realmente complicado, mas pode ser uma boa opção. Ainda seria possível enviar certos URLs para determinados servidores? Como agora no HAProxy, todos os URLs que terminam na extensão de arquivo correta são enviados para o Lighttpd, enquanto outras extensões são enviadas para o Apache. Então, eu precisaria de algo semelhante. Assim, todas as solicitações de php são tratadas pelo mesmo servidor que executa o software de balanceamento, enquanto todas as solicitações de jpg são enviadas para vários servidores.

Idealmente, se o HAProxy suportasse o Direct Server Return, meu problema seria resolvido. Também não quero usar uma CDN, porque são muito caras e, afinal, esse é apenas um projeto paralelo.

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


1
Este é Imgur e recentemente levantou 40 milhões de dólares. : O
L1th1um

Respostas:


3

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

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


Muito obrigado. Os resultados da sua pesquisa foram muito úteis. Penso que esta é a solução a que finalmente chegarei. No entanto, "Como qualquer bom pesquisador, não ajo até ter dados suficientes". :)
Alan

Obrigado pela compreensão. Infelizmente, ironicamente, o link para suas descobertas parece estar inoperante, você pode consertar?
TCB13

3

Algumas respostas:

  • Sim, todo o tráfego passa pelo HAProxy, pois funciona como um proxy no nível HTTP. Será o mesmo, mesmo se o HAProxy estiver instalado em um servidor separado que carrega o equilíbrio de vários servidores back-end. Portanto, se o seu provedor de hospedagem fornecer apenas portas de rede de 100 MBit e você já estiver pressionando 100 MBit, 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 domínio diferente, para que os cookies não sejam enviados junto com as solicitações de imagem. Veja o trabalho original de Steve Souders ou a implementação aqui no Stack Overflow . Se URLs curtos forem muito importantes para você, talvez o melhor seja mover o aplicativo da Web para fora 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 imagem? Caso contrário, que tal usar algo como o Amazon S3? É massivamente escalável, e o custo de transferência de dados é bastante barato. Nesse caso, eu usaria algo como i.sitename.com como um CNAME DNS para o nome do host do bucket do Amazon S3, consulte a documentação da Amazônia . AFAIK, você não pode ter o nome de domínio raiz (sitename.com) como CNAME; portanto, você deve usar um subdomínio como i.sitename.com para isso.

Você também pode misturar suas imagens em vários servidores. Ou seja, você cria uma estrutura DNS como login.sitename.com e a.sitename.com; b.sitename.com; c.sitename.com e outros. O "a". e B." Os servidores etc apenas contêm um sistema de arquivos com imagens e um servidor HTTP leve (você já está usando o Lighttpd, continue usando isso. Para um projeto futuro, proponho olhar o nginx como um substituto melhor.) Quando um usuário faz o upload uma imagem, você cria um hash de um identificador exclusivo, talvez o 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 o hash já foi discutido. Essencialmente, o que estou propondo aqui é apenas usar hash no nome do host, para espalhar o tráfego de rede igualmente em vários hosts.

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


1

Presumo que o HAProxy esteja no mesmo servidor que seus outros aplicativos? Você pode dividir o HAProxy em outro sistema para executar as solicitações e enviar solicitações normais para um servidor e solicitações de imagem para outro servidor. A questão é que todas as solicitações ainda estão indo para uma caixa e, se você está saturando a largura de banda, isso pode não ajudar muito.

Você diz que URLs curtos são importantes. Por quê? É realmente importante mudar imagens de "example.com" para "i.example.com"? Você pode definir "i" como seu próprio IP em seu próprio servidor com o Lighttpd e ignorar completamente o HAProxy, resolvendo seu problema de taxa de transferência. Você também obteria o benefício do navegador da Web, permitindo a abertura de mais solicitações de uma só vez, uma vez que as consideraria nomes de domínio diferentes e poderia abrir mais conexões simultâneas. Se o único servidor "i" ficar saturado, você poderá usar o round-robin do DNS para adicionar outro. Espero que, nesse momento, você esteja gerando receita suficiente para implementar uma solução melhor.


Sim, o HAProxy está no mesmo servidor - só tenho um até agora. Mesmo se eu o dividisse em outro servidor, todos os dados ainda não passariam pelo servidor com o HAProxy, como expliquei acima? URLs curtos são importantes porque esse é o objetivo do site. É um cruzamento entre o ImageShack e o TinyPic. Quanto maior o URL, menos ponto o meu site tem. Mas como eu disse, se a única opção viável é configurar um subdomínio, então eu precisaria fazê-lo. Eu realmente preferiria não fazer isso.
Alan

1

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 (com muita clareza ou apache) os pedidos. Por exemplo: example.com/file.html permanece no apache e example.com/image.jpg é redirecionado para i.example.com/image.jpg. Todas as solicitações serão gerenciadas através do apache, mas as respostas (largura de banda upstream) 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 todos os pedidos ou se o lighttpd pode fazer esse trabalho.

Você está certo, todos os dados passam pelo HAProxy, portanto, você não pode (tanto quanto eu sei) retornar diretamente ao servidor com ele.

ATUALIZAR

Procurando na documentação do HAproxy, encontrei o parâmetro "redir". Não sei se ele funciona como reescrever o apache, mas pode ser útil. A documentação diz:

O uso principal consiste em aumentar a largura de banda para servidores estáticos, fazendo com que os clientes se conectem diretamente a eles.

Talvez funcione para o seu caso.


Ei, obrigado pela resposta. Na verdade, eu já tentei isso e não funciona tão bem na prática quanto na teoria. O motivo é que o Apache lida com todas as solicitações; assim, toda vez que um usuário acessa uma imagem, o Apache é gerado, analisa o URL e envia para ele com muita luz. O que não é diferente, basta fazer o Apache manipular a imagem em primeiro lugar. Concordo que um balanceador de carga fornecido pelo meu host é a melhor opção, mas também é um dos mais caros. Eles cobram por conexão simultânea, e eu recebo centenas deles.
Alan

É diferente na maneira como o servidor poderoso envia a resposta diretamente ao cliente consumindo sua própria largura de banda. O problema é que o servidor Apache processará muitas solicitações. Verifique a atualização para a minha resposta, encontrei outra solução.
hdanniel

1

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

Muitos aplicativos que lidam com esses tipos de problemas usam o hash do arquivo e uma estrutura de diretório com base nesse hash. A estrutura de diretórios se parece com a seguinte, em que o caminho do diretório é os dois primeiros caracteres do hash e o diretório de segundo nível é os próximos 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 dos arquivos bastante uniforme e fornece um espaço para nome fácil de dividir em vários servidores. Basicamente, você serve partes do espaço de hash de diferentes servidores e, à medida que aumenta a escala, pode subdividi-lo ainda mais, conforme necessário.

A desvantagem é que os hashes não são perfeitos e pode haver colisões. Não tenho certeza de como isso é tratado. Portanto, isso pode exigir um pouco de pesquisa de sua parte. Eu imagino que uma regra de reescrita no proxy possa pegar um hash, digamos A3A8BBC83261.jpg e reescrevê-la para http://img3.domain.com/A3/A8/BBC83261.jpg . Você não pode considerar isso um URL curto.


Sim, é exatamente assim que estou armazenando as imagens. No entanto, o problema não está no armazenamento, mas na distribuição da largura de banda.
2727 Alan Alan

Mas se você armazenar AA a 33 em um servidor e 34 a 99 em outro servidor, não apenas equilibrará o problema de armazenamento, mas também a distribuição da largura de banda.
3dinfluence

0

Na sua postagem, você mencionou que achava que o round robbin do DNS 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 no passado e funciona muito bem.

http://www.simplefailover.com

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

Aqui está um trecho do site:

O Failover simples monitora continuamente seus servidores para descobrir quais estão ativos e quais estão inativos e, em seguida, atualiza dinamicamente seus registros DNS de acordo, para que seu nome de domínio sempre aponte para um servidor funcional.

Funciona com servidores Web (HTTP), servidores de correio (SMTP, IMAP, POP3), servidores FTP e praticamente qualquer outro tipo de servidor baseado em TCP / IP.

Como mencionado anteriormente, eu o usei no passado para sites e servidores de email. O desempenho foi bom. O failover foi bastante rápido na maioria dos casos (supondo de 2 a 5 minutos) e eu diria que quase todo mundo fez failover em menos de 15 minutos.

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

NOTA: Este é um produto do Windows. Não tenho certeza se eles têm uma versão linux ou não, mas você pode executar o failover de qualquer servidor que desejar desde que seja baseado em DNS.

No nosso caso, apenas o jogamos em uma máquina XP, pedimos para a máquina reiniciar uma vez por noite e funcionou bem por anos.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.