Pergunta

Estou passando por um pouco de um re-pensar, em grande escala, jogos multiplayer na era do Facebook e aplicativos de cloud computing.

Suponha que eu fosse para construir algo em cima do existente protocolos abertos, e eu quero servir de 1.000.000 de jogadores simultâneos, apenas para definir o escopo do problema.

Suponha que cada jogador tem uma fila de mensagem de entrada (para bate-papo e outras coisas mais), e uma média de mais fila de mensagem de entrada (guildas, horários, instâncias, leilão, ...) por isso temos de 2.000.000 de filas.Um jogador vai ouvir 1-10 filas de cada vez.Cada fila terá, em média, talvez 1 mensagem por segundo, mas certas filas terá taxa muito mais elevada e maior número de ouvintes (digamos, uma "entidade local" fila para uma instância de nível superior).Vamos supor que não mais do que 100 milissegundos de sistema de enfileiramento de latência, que é OK para levemente orientada para a acção, jogos (mas não de jogos como Quake ou Unreal Tournament).

A partir de outros sistemas, eu sei que servir de 10.000 usuários em um único 1U ou lâmina de caixa é uma expectativa razoável (supondo que não há nada mais caro acontecendo, como simulação de física ou outros enfeites).

Assim, com uma trave sistema de cluster, onde os clientes se conectam a conexão de gateways, que por sua vez se conectar a fila de mensagens de servidores, gostaríamos de obter 10.000 usuários por gateway com 100 gateway de máquinas e 20.000 filas de mensagens por queue server com 100 fila de máquinas.Novamente, apenas para geral o escopo.O número de conexões em cada MQ máquina seria minúsculo:cerca de 100, para falar a cada um dos gateways.O número de conexões nos gateways iria ser muito maior:10,100 para os clientes + conexões para toda a fila de servidores.(Sobre isso, adicione algumas ligações para o mundo de jogo de simulação de servidores ou outros enfeites, mas estou tentando manter o que separados por agora)

Se eu não querer construir isso a partir do zero, eu teria que usar algumas mensagens e/ou na fila de infra-estrutura que existe.Os dois protocolos abertos eu posso encontrar são AMQP e XMPP.O uso pretendido do XMPP é um pouco mais parecido com o que este sistema de jogo seria necessário, mas a sobrecarga é bastante perceptível (XML, mais detalhado, os dados de presença, além de vários outros canais que tem que ser construída em cima).O actual modelo de dados do AMQP é mais próximo do que eu descrevo acima, mas todos os usuários parecem ser grandes, do tipo empresarial corporações, e as cargas de trabalho parecem ser de fluxo de trabalho relacionados, não do jogo em tempo real relacionados com a actualização.

Alguém tem alguma experiência durante o dia com estas tecnologias, ou suas implementações, que você pode compartilhar?

Foi útil?

Solução

@MSalters

Re 'message queue':

RabbitMQ padrão de operação é exatamente o que você descreve:transitória minha.Mas com o TCP em vez de UDP.

Se você deseja garantido eventual entrega e outros persistência e recuperação de recursos e, em seguida, você também PODE tê-la - é uma opção.Esse é o ponto inteiro do RabbitMQ e AMQP -- você pode ter muita comportamentos com apenas uma mensagem de sistema de entrega.

O modelo que descreve o comportamento PADRÃO, que é transitório, "fire and forget", e o roteamento de mensagens para onde quer que os destinatários são.As pessoas usam RabbitMQ para fazer multicast descoberta no EC2, apenas por essa razão.Você pode obter UDP tipo de comportamentos sobre unicast TCP minha.Puro, hein?

Re UDP:

Eu não tenho certeza se UDP seria útil aqui.Se você desativar Nagling, em seguida, RabbitMQ única mensagem a latência de ida e volta (cliente-corretor-cliente) foi medida em 250 a 300 microssegundos.Veja aqui uma comparação com o Windows latência (o que foi um pouco superior) http://old.nabble.com/High%28er%29-latency-with-1.5.1--p21663105.html

Eu não posso pensar em muitos jogos multiplayer que precisa de ida e volta de latência inferior a 300 microssegundos.Você poderia ficar abaixo 300us com o TCP.TCP janelas é mais caro do que matérias-UDP, mas se você usa o UDP para ir mais rápido, e adicionar um personalizado de perda de recuperação ou seqno/ack/reenviar manager, em seguida, que podem atrasar você para baixo novamente.Tudo depende do seu caso de uso.Se você realmente precisa utilizar o UDP e preguiçoso acks e assim por diante, em seguida, você pode excluir RabbitMQ TCP e, provavelmente, fazer aquilo.

Espero que isso ajude a esclarecer o porquê de eu recomendada RabbitMQ para Jon caso de uso.

Outras dicas

Estou construindo esse sistema agora, na verdade.

Fiz uma boa quantidade de avaliação de vários MQs, incluindo RabbitMQ, QPID e ZEROMQ. A latência e a taxa de transferência de qualquer um deles são mais do que adequados para esse tipo de aplicação. O que não é bom, no entanto, é o tempo de criação da fila em meio a meio milhão de filas ou mais. O QPID, em particular, degrada severamente após alguns milhares de filas. Para contornar esse problema, você normalmente precisará criar seus próprios mecanismos de roteamento (número menor de filas totais, e os consumidores nessas filas estão recebendo mensagens nas quais eles não têm interesse).

Meu sistema atual provavelmente usará o ZerOMQ, mas de uma maneira bastante limitada, lado de dentro o cluster. As conexões dos clientes são tratadas com um SIM personalizado. Daemon que eu construí usando Libev e é totalmente threadned (e está mostrando uma escala muito boa-ele deve ser capaz de lidar com 50.000 conexões em uma caixa sem problemas-nossa taxa de tick sem física).

O XML (e, portanto, XMPP) não é muito adequado para isso, pois você atingirá o XML de processamento da CPU muito antes de você se encaixar na E/S, o que não é o que você deseja. Estamos usando os buffers do Google Protocol, no momento, e esses parecem adequados às nossas necessidades específicas. Também estamos usando o TCP para as conexões do cliente. Eu tive experiência em usar o UDP e o TCP para isso no passado e, como apontado por outros, o UDP tem alguma vantagem, mas é um pouco mais difícil de trabalhar.

Felizmente, quando estivermos um pouco mais próximos do lançamento, poderei compartilhar mais detalhes.

Jon, isso soa como um caso de uso ideal para AMQP e RabbitMQ.

Não sei por que você diz que os usuários do AMQP são todos grandes corporações do tipo empresarial. Mais da metade de nossos clientes está no espaço 'web', variando de grandes a pequenas empresas. Muitos jogos, sistemas de apostas, sistemas de bate -papo, sistemas de tipos de twittery e infra -de -computação em nuvem foram construídos a partir do RabbitMQ. Existem até aplicativos de telefone celular. Os fluxos de trabalho são apenas um dos muitos casos de uso.

Tentamos acompanhar o que está acontecendo aqui:

http://www.rabbitmq.com/how.html (Certifique -se de clicar nas listas de casos de uso no del.icio.us também!)

Por favor, dê uma olhada. Estamos aqui para ajudar. Sinta -se à vontade para nos enviar um e -mail para info@rabbitmq.com ou bata no Twitter (@monadic).

O FWIW, para casos em que os resultados intermediários não são importantes (como informações de posicionamento), o QPID possui uma "fila de último valor" que pode oferecer apenas o valor mais recente a um assinante.

Minha experiência foi com uma alternativa não aberta, BizTalk. A lição mais dolorosa que aprendemos é que esses sistemas complexos não são rápidos. E como você imaginou a partir dos requisitos de hardware, isso se traduz diretamente em custos significativos.

Por esse motivo, nem chegue perto do XML para as interfaces principais. Seu cluster de servidor estará analisando 2 milhões de mensagens por segundo. Isso pode ser facilmente 2-20 GB/s de XML! No entanto, a maioria das mensagens será para algumas filas, enquanto a maioria das filas é de fato baixa tráfego.

Portanto, projete sua arquitetura para que seja fácil começar com os servidores da fila do COTS e mover cada fila (tipo) para um servidor de fila personalizado quando um gargalo for identificado.

Além disso, por razões semelhantes, não assuma que uma arquitetura da fila de mensagens é a melhor para todas as necessidades de cominicação que seu aplicativo possui. Pegue o exemplo do seu exemplo "localização da entidade em um exemplo". Este é um caso clássico em que você não deseja entrega de mensagem garantida. A razão pela qual você precisa compartilhar essas informações é porque elas mudam o tempo todo. Portanto, se uma mensagem for perdida, você não deseja gastar tempo recuperando -a. Você enviaria apenas a antiga locatioma da entidade afetada. Em vez disso, você gostaria de enviar o atual Localização dessa entidade. Em termos de tecnologia, isso significa que você deseja UDP, não TCP e um mecanismo de recuperação de perdas personalizado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top