Cola de mensajes de baja latencia y gran escala


Estoy pasando por un poco de repensar los juegos multijugador a gran escala en la era de las aplicaciones de Facebook y la computación en la nube.

Supongamos que tuviera que construir algo sobre protocolos abiertos existentes, y quiero servir a 1.000.000 de jugadores simultáneos, solo para analizar el problema.

Supongamos que cada jugador tiene una cola de mensajes entrantes (para chat y demás), y en promedio una cola de mensajes entrantes más (gremios, zonas, instancias, subastas,... así que tenemos 2.000.000 colas. Un jugador escuchará de 1 a 10 colas a la vez. Cada cola tendrá en promedio tal vez 1 mensaje por segundo, pero ciertas colas tendrán una tasa mucho más alta y un mayor número de oyentes (por ejemplo, una cola de "ubicación de entidad" para una instancia de nivel). Supongamos que no más de 100 milisegundos de latencia de cola del sistema, lo cual está bien para juegos ligeramente orientados a la acción (pero no juegos como Quake o Unreal Tournament).

De otros sistemas, sé que servir a 10,000 usuarios en una sola 1U o blade box es una expectativa razonable (suponiendo que no hay nada más caro pasando, como la simulación física o lo que sea).

Entonces, con un sistema de clústeres de barras cruzadas, donde los clientes se conectan a puertas de enlace de conexión, que a su vez se conectan a servidores de cola de mensajes, obtendríamos 10.000 usuarios por puerta de enlace con 100 máquinas de puerta de enlace, y 20.000 colas de mensajes por servidor de cola con 100 máquinas de cola. Una vez más, sólo para el alcance general. El número de conexiones en cada máquina MQ sería pequeño: alrededor de 100, para hablar con cada una de las puertas. El número de conexiones en las puertas de enlace sería mucho mayor: 10.100 para los clientes + conexiones a todos los servidores de cola. (Además de esto, agregue algunas conexiones para servidores de simulación del mundo del juego o lo que sea, pero estoy tratando de mantener eso separado por ahora)

Si no quisiera construir esto desde cero, tendría que usar alguna infraestructura de mensajería y/o colas que existe. Los dos protocolos abiertos que puedo encontrar son AMQP y XMPP. El uso previsto de XMPP es un poco más como lo que este sistema de juego necesitaría, pero la sobrecarga es bastante notable (XML, además de los datos de presencia detallados, además de varios otros canales que tienen que ser construidos en la parte superior). El modelo de datos real de AMQP es más cercano a lo que describo anteriormente, pero todos los usuarios parecen ser grandes corporaciones de tipo empresarial, y las cargas de trabajo parecen estar relacionadas con el flujo de trabajo, no relacionadas con la actualización del juego en tiempo real.

¿Alguien tiene alguna experiencia diurna con estas tecnologías, o implementaciones de las mismas, ¿que puedes compartir?

Author: Jon Watte, 2009-12-17

5 answers

@ MSalters

Re 'message queue':

La operación predeterminada de RabbitMQ es exactamente lo que describe: transient pubsub. Pero con TCP en lugar de UDP.

Si desea una entrega eventual garantizada y otras características de persistencia y recuperación, también puede tener eso: es una opción. Ese es el punto de RabbitMQ y AMQP you puedes tener muchos comportamientos con un solo sistema de entrega de mensajes.

El modelo que describe es el comportamiento PREDETERMINADO, que es transient, "fire and forget", y enrutamiento de mensajes a donde estén los destinatarios. La gente usa RabbitMQ para hacer multicast discovery en EC2 precisamente por esa razón. Puede obtener comportamientos de tipo UDP a través de unicast TCP pubsub. Genial, ¿eh?

Re UDP:

No estoy seguro de si UDP sería útil aquí. Si desactiva Nagling, entonces la latencia de ida y vuelta de un solo mensaje de RabbitMQ (cliente-corredor-cliente) se ha medido en 250-300 microsegundos. Vea aquí para una comparación con la latencia de Windows (que fue un poco más alto) http://old.nabble.com/High%28er%29-latency-with-1.5.1--p21663105.html

No puedo pensar en muchos juegos multijugador que necesitan latencia de ida y vuelta inferior a 300 microsegundos. Usted podría conseguir debajo de 300us con TCP. TCP windowing es más caro que raw UDP, pero si usa UDP para ir más rápido, y agrega un gestor de recuperación de pérdidas personalizado o seqno/ack/resend entonces eso puede ralentizarlo de nuevo. Todo depende de su caso de uso. Si realmente realmente necesitas utilice UDP y acks perezosos y así sucesivamente, entonces usted podría quitar TCP de RabbitMQ y probablemente sacar eso.

Espero que esto ayude a aclarar por qué recomendé RabbitMQ para el caso de uso de Jon.

 11
Author: alexis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-29 16:48:33

Estoy construyendo tal sistema ahora, en realidad.

He hecho una buena cantidad de evaluación de varios MQs, incluyendo RabbitMQ, Qpid y ZeroMQ. La latencia y el rendimiento de cualquiera de ellos son más que adecuados para este tipo de aplicaciones. Lo que no es bueno, sin embargo, es el tiempo de creación de colas en medio de medio millón de colas o más. Qpid en particular se degrada severamente después de unos pocos miles de colas. Para evitar ese problema, normalmente tendrá que crear su propio mecanismos de enrutamiento (menor número de colas totales, y los consumidores en esas colas reciben mensajes en los que no tienen interés).

Mi sistema actual probablemente usará ZeroMQ, pero de una manera bastante limitada, dentro de el clúster. Las conexiones de los clientes se manejan con una sim personalizada. daemon que construí usando libev y es completamente de un solo hilo (y está mostrando muy buena escala should debería ser capaz de manejar 50,000 conexiones en una caja sin ningún problema our nuestro SIM. sin embargo, la tasa de garrapatas es bastante baja, y no hay física).

XML (y por lo tanto XMPP) no es muy adecuado para esto, ya que pegará el XML de procesamiento de la CPU mucho antes de quedar enlazado en E/S, que no es lo que desea. Estamos usando Búferes de protocolo de Google, en este momento, y esos parecen muy adecuados para nuestras necesidades particulares. También estamos usando TCP para las conexiones del cliente. He tenido experiencia usando UDP y TCP para esto en el pasado, y como han señalado otros, UDP lo hace tener alguna ventaja, pero es un poco más difícil de trabajar con.

Con suerte, cuando estemos un poco más cerca del lanzamiento, podré compartir más detalles.

 10
Author: Tim McClarren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-03 18:15:41

Jon, esto suena como un caso de uso ideal para AMQP y RabbitMQ.

No estoy seguro de por qué dices que todos los usuarios de AMQP son grandes corporaciones de tipo empresarial. Más de la mitad de nuestros clientes se encuentran en el espacio 'web' que va desde grandes empresas hasta pequeñas empresas. Muchos juegos, sistemas de apuestas, sistemas de chat, sistemas de twittery e infraestructura de computación en la nube se han construido a partir de RabbitMQ. Incluso hay aplicaciones para teléfonos móviles. Los flujos de trabajo son solo uno de los muchos casos de uso.

Tratamos de mantener pista de lo que está pasando aquí:

Http://www.rabbitmq.com/how.html (asegúrese de hacer clic en las listas de casos de uso en del.icio.us ¡también!)

Por favor, eche un vistazo. Estamos aquí para ayudar. No dude en enviarnos un correo electrónico a [email protected] o me golpeó en twitter (@monadic).

 5
Author: alexis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-29 16:48:05

FWIW, para los casos en los que los resultados intermedios no son importantes (como la información de posicionamiento), Qpid tiene una "cola de último valor" que puede entregar solo el valor más reciente a un suscriptor.

 3
Author: Steve Huston,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-29 17:37:43

Mi experiencia fue con una alternativa no abierta, BizTalk. La lección más dolorosa que aprendimos es que estos sistemas complejos NO son rápidos. Y como se imaginó a partir de los requisitos de hardware, eso se traduce directamente en costos significativos.

Por esa razón, ni siquiera se acerque a XML para las interfaces principales. Su clúster de servidores analizará 2 millones de mensajes por segundo. Eso podría ser fácilmente 2-20 GB/seg de XML! Sin embargo, la mayoría de los mensajes serán para algunas colas, mientras que la mayoría de las colas están en hecho de poco tráfico.

Por lo tanto, diseñe su arquitectura para que sea fácil comenzar con los servidores de cola COTS y luego mover cada cola (tipo) a un servidor de cola personalizado cuando se identifique un cuello de botella.

Además, por razones similares, no asuma que una arquitectura de cola de mensajes es la mejor para todas las necesidades de comunicación que tiene su aplicación. Tome el ejemplo de "ubicación de la entidad en una instancia". Este es un caso clásico en el que no quiere una entrega de mensajes garantizada. El la razón por la que necesita compartir esta información es porque cambia todo el tiempo. Por lo tanto, si se pierde un mensaje, no querrá pasar tiempo recuperándolo. Sólo enviarías la antigua ubicación de la entidad afectada. En su lugar, usted querrá enviar la ubicación actual de esa entidad. En cuanto a la tecnología, esto significa que desea UDP, no TCP y un mecanismo personalizado de recuperación de pérdidas.

 2
Author: MSalters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-18 14:38:26