¿Cuál es la mejor arquitectura de servidor para juegos en tiempo real?

10

Estoy desarrollando un juego en tiempo real que debería contener a miles de jugadores en tiempo real (como FPS como retraso máximo de 1s). ¿Cuál sería la mejor infraestructura para esto?

Mi idea era usar 2 clústeres de servidores, uno para el extremo del servidor (todo el lado de la informática) y otro para el extremo de la base de datos, donde un equilibrador de carga es "responsable" de cada uno de los clústeres. Un servidor principal recibirá las solicitudes de los usuarios y devolverá la dirección IP del servidor relevante para que el usuario pueda trabajar con esto.

El clúster de la base de datos utilizará la replicación de la base de datos para mantener la coherencia entre las bases de datos.

También debería haber un equilibrador de carga geográfico, por lo que asignará el equilibrador de carga regional a cada usuario para obtener la mejor respuesta.

Estoy usando .NET + MSSQL para el juego.

¡Gracias!

romano
fuente
2
Cuando dice "infraestructura", ¿se refiere a software, hardware, servicios o simplemente quiere que critiquemos su plan actual tal como está?
Tetrad
1
@Nate: estamos planeando escalar, no duplicar, por lo que debería ser totalmente escalable.
romano
2
-1 porque teddziuba.com/2008/04/im-going-to-scale-my-foot-up-y.html - No cubres ningún requisito de capacidad, dices que el juego no está fragmentado pero está dividido en zonas , etc. La naturaleza de las optimizaciones de rendimiento, incluida la escalabilidad, requiere información específica y no existe la mejor arquitectura absoluta.
1
Reformularía tu pregunta a algo más concreto. ¿Qué es "mejor", de manera objetiva y no subjetiva? ¿Te refieres a más fácil de escalar, más fácil de administrar, más fácil de poner en marcha, más rápido o qué?
El pato comunista
1
"Más fácil" también es subjetivo. ¿Más fácil para quién, en qué período de tiempo, dados los recursos? Stack Exchanges funciona mejor con preguntas específicas: "He creado este servidor usando LINQ y MSSQL, pero se cayó después de 70 transacciones / segundo, aquí están mis dos transacciones principales que representan el 73% de mi tiempo de ejecución, ¿cómo debo aumentar mi rendimiento? "

Respuestas:

6

No hay mejor arquitectura sin saber mucho más sobre sus requisitos, por ejemplo. el tipo de interacciones entre los personajes, la cantidad de datos que serán persistentes, etc.

Si puede hacer frente a 1 segundo de latencia, probablemente pueda alojar 1000 jugadores en un solo servidor sin problemas, pero eso en realidad entra en conflicto con la idea de un FPS, ya que generalmente requieren una latencia mucho más baja, por ejemplo. Menos de 100ms. Pero un sistema que puede lidiar con una alta latencia puede permitirse hacer todo a través del envío de mensajes, lo que hace que la consistencia sea bastante trivial. Proporcionar su lógica es bastante simple, es decir, la lógica compleja empeora aún más cuando la convierte en un sistema basado en mensajes en lugar de un sistema de objetos bloqueados, pero todo depende de las necesidades de su aplicación.

Del mismo modo, si no persiste mucha información, no necesita la máquina de la base de datos, pero sin saberlo, es difícil de decir. Si persiste pequeñas cantidades de datos, y tal vez solo lo hace al final de un torneo o algo así, nuevamente no necesita una base de datos separada, ciertamente no un grupo de ellos. Por otro lado, si no persiste mucho pero lee mucho, ahí es donde las bases de datos replicadas pueden ayudarlo, pero también indica que una base de datos relacional puede no ser la mejor opción para su problema en primer lugar. A menudo, un caché en memoria es una mejor solución. Del mismo modo, si no hay interacciones de estilo de transacción entre caracteres, la consistencia se vuelve menos importante. (Y si solo hay unas pocas transacciones de este tipo, puede convertirlas en un caso especial).

De hecho, tenga cuidado de adoptar un RDBMS solo porque es lo que se hace en sistemas grandes. Aunque personalmente apruebo usarlos en juegos en línea, es mejor observar sus requisitos y descubrir su estrategia de persistencia a partir de eso, en lugar de tomar su base de datos preferida y luego tratar de ajustarla con cachés y replicación para que se ajuste a su aplicación Puede encontrar que todo lo que necesita es la capacidad de informes fuera de línea, en cuyo caso probablemente sea mejor tener un registro de proceso en segundo plano desde su mecanismo de persistencia del juego en un RDBMS remoto en otro lugar.

Kylotan
fuente
4

Descargo de responsabilidad: mi experiencia en programación de juegos se basa en juegos de un solo jugador del lado del cliente, pero tengo experiencia en aplicaciones web (específicamente en la pila de Microsoft), así que de ahí vengo con esta respuesta, creo que eso sería aplicar, pero sin probar realmente un servidor de juego real es difícil decir cómo se aplicará, pero aquí va. Sepa esto: no he implementado un servidor de juegos, solo aplicaciones web.

Sugeriría un enfoque de dos niveles (servidor). Un nivel de base de datos y un nivel de "aplicación"; con el tercer nivel (presentación) siendo su cliente del juego.

Las bases de datos relacionales son excelentes para consultar datos y decentes para escribir datos. La clave es serializar las escrituras de su base de datos en fragmentos de tamaño manejable que su clúster puede manejar. Las ediciones más avanzadas (centro de datos / empresa) de SQL Server admiten la agrupación y la replicación. Comenzaría construyendo un pequeño clúster y ejecutando algunas consultas para ver cómo funciona.

En el nivel de aplicación, si está haciendo "zonificación" o algo similar, probablemente pueda escapar sin configurar ningún clúster y simplemente configurar un servidor por zona. Si sus zonas se vuelven demasiado grandes, puede configurar un clúster para cada zona.

Deberá crear un proceso de serialización para enviar datos desde el nivel de aplicación -> nivel de base de datos. La clave es tener múltiples niveles de serialización en curso. Algo como esto:

  • Nivel 1: Guardar en DB cada X segundos, incluye datos críticos:
    • Salud del jugador
    • Artículos del jugador / pastillas
  • Nivel 2: Guardar en DB cada 2X segundos, incluye datos medios:
    • Ubicaciones de jugadores
    • Ubicaciones de NPC
  • Nivel 3: todo lo demás, con la menor frecuencia posible

Esto mantendrá tus escrituras consistentes y predecibles, dependiendo de la naturaleza de tu juego, podrías tener escrituras infrecuentes en la base de datos. La clave es darse cuenta de que si su servidor de aplicaciones fallaba, tendría que volver a conectarse desde el estado en su base de datos, por lo que serializar el inventario de jugadores cada 90 minutos podría molestar a los jugadores.

Para leer datos, querrá cargar tanto como sea posible en la memoria en el nivel de aplicación posible, luego asegurarse de que todo su código use este grupo de memoria, en segundo plano puede sincronizar el grupo de memoria con la base de datos. Como Joe señala, habrá momentos en los que necesitará transacciones "en tiempo real". Al serializar la mayoría de sus escrituras, aún debe tener suficiente E / S en su base de datos para realizar transacciones en tiempo real cuando sea necesario, suponiendo que haya suficiente hardware en el servidor / clúster de la base de datos.

Nate
fuente
-1 porque acabas de tirar ACID y solo estás usando la base de datos como un gran almacén de datos. Está bien, el programador de discos de Windows es lo suficientemente malo como para seguir siendo una ganancia de rendimiento, y probablemente puedas hacer algunas métricas sin conexión ordenadas con los datos que contiene, pero aún necesitas ACID, es decir, una base de datos, que respalde las transacciones en el juego, en tiempo real (ish).
Aunque escaso, eso es a lo que iba en el último párrafo. Estoy recomendando un poco de híbrido, donde use IN-Memory cuando sea posible, y la base de datos cuando sea necesario.
Nate
El problema es que ha pasado por alto lo que hay en la memoria, que es una base de datos completamente diferente, y no ha dado instrucciones sobre cómo implementar eso, que es el verdadero truco.
Es cierto, aunque la pregunta era sobre la arquitectura del panorama general, no sobre los detalles de implementación.
Nate
Es cierto, pero has omitido todo el nivel medio. ¿Es un RDB de baja latencia? Un ODB? ¿Tienda de clave / valor? No DB y renunciar a ACID? STM o bloqueo? Para ser justos, es muy difícil responder eso porque no hay mucha información en la pregunta, pero toda esta respuesta al diagrama de arquitectura es tomar la gran burbuja en el medio con un "?" en él y conectar dos servicios más a él, en realidad no completar qué "?" es.