Imagine un mundo abierto de más de 500 jugadores con datos que cambian tan rápido como 20 actualizaciones / jugador / segundo. La última vez que trabajé en un MMORPG similar, usó SQL, por lo que obviamente no podía consultar la base de datos todo el tiempo. En cambio, cargó a todos los jugadores desde la base de datos a la memoria como objetos C ++ y los usó. Es decir, se escaló verticalmente. ¿Sería posible hacer que ese servidor sea escalable horizontalmente? ¿Existe una base de datos diseñada para admitir esa cantidad de actualizaciones al mismo tiempo?
mmo
data-structure
databases
scalability
MaiaVictor
fuente
fuente
Respuestas:
Caso de prueba de 500 jugadores que se comunican, eso es 250,000 flujos de información que vuelan a 20Hz. El ancho de banda interno para eso sería, suponiendo 100 bytes por mensaje, aproximadamente 500 MB / seg. Suena ambicioso Especialmente entre procesos.
Si segrega a los jugadores a grupos de 100, eso se reduce a 20 MB / seg, y así sucesivamente. Es por eso que los MMO tienen zonas, y en esas zonas pequeñas burbujas de influencia, y así sucesivamente hacia abajo hasta que el ancho de banda sea razonable.
El problema original se puede afirmar que si tienes 10 personas que comparten información en tiempo real, pero quieres que todas compartan 500 , eso es un crecimiento exponencial de los enlaces de comunicación y cómo podemos evitarlo . Me temo que no he oído hablar de una bala mágica que mágicamente pueda hacer que la progresión geométrica desaparezca.
No use una base de datos para comunicarse, para eso está la mensajería. Use la base de datos para imponer transacciones y almacenar información que no desea que los jugadores pierdan. La mayoría de los MMO con los que estoy familiarizado solo actualizan la base de datos con información dinámica del jugador cada 1-10 minutos, o en puntos útiles como transiciones de zona o ingresando zonas "seguras" en el diseño.
Es posible que tengas que rediseñar la necesidad del juego para cada jugador, sin importar qué tan lejos esté, para tener actualizaciones en tiempo real del contenido de la mochila de cada otro jugador.
También cambie el patrón de actualización de 20Hz a una velocidad basada en la distancia, alguien a 1 milla de distancia no necesita saber que movió 1 pie exactamente a 230.6 segundos, luego otro pie a 231.4 segundos, pueden lidiar con usted moviéndose 15 pies cada 10 segundos.
fuente
Utilice el filtrado del área de interés. Si un mundo se divide en 3 servidores, y el área del servidor 1 no está cerca del área del servidor 3, no hay ninguna razón para que compartan información sobre entidades.
Del mismo modo, en un solo servidor, solo envíe información relevante a los clientes. Si el jugador A está en el extremo totalmente opuesto del mapa del jugador B, no hay razón para enviar actualizaciones sobre B a A, o viceversa.
Cuando tiene varios servidores en un mundo continuo, tendrá entidades cercanas a un borde en el servidor 2 que están cerca de las entidades en el servidor 1. Puede enviar actualizaciones desde el servidor "autorizado" de una entidad al otro servidor (cuando corresponda) y del mismo modo reenviar cualquier mensaje al servidor autorizado según corresponda.
Sí, en este caso, un servidor estará un poco desactualizado para entidades particulares. No trates de resolver eso. Simplemente trata con ello. Suponga que las entidades pueden estar un poco desactualizadas. Haga cualquier lógica que necesite información actualizada solo en el servidor que posee las entidades con autoridad. Cuando una entidad afecta a otra, envía un mensaje y asume que puede tomar múltiples tics lógicos del juego antes de que se procese y tu vista se actualice.
Este diseño también hace que sea mucho más fácil enhebrar un solo servidor. Ninguna entidad debe modificar directamente a otra, solo enviar mensajes, y se debe suponer que las cachés de proxy locales por servidor / por subproceso están ligeramente desactualizadas.
Por ejemplo, si la entidad A ataca a la entidad B, no verifique la vida de B y luego envíe un mensaje de muerte si llega a 0. Simplemente envíe un mensaje "dañado", deje que el servidor autorizado de B lo maneje, y luego maneje cualquier Mensaje "entidad fallecida" enviado por el servidor B más tarde si la entidad A se preocupa por eso.
Lo mismo se aplica a cualquier aplicación grande y escalable que no sea de juegos. Una base de datos central no es una tecnología mágica para compartir instantáneamente. Dos servidores deben comunicarse con mensajes, asincrónicamente, en lotes, para mantener un alto rendimiento. De ahí la popularidad de tecnologías como AMPQ y similares. Las bases de datos son para el almacenamiento y la sincronización de soporte por necesidad, lo que les permite ser utilizadas para las comunicaciones, no porque estén destinadas a la sincronización o la comunicación.
fuente
Probablemente le interesará este artículo sobre Gamasutra , donde los desarrolladores de Eve Online discuten cómo es posible ejecutar con éxito un juego con 400 000 jugadores activos ... en una base de datos SQL.
fuente
No piense en la base de datos como un modelo de mundo compartido amable en tiempo real que almacena todo sobre todo en todo momento, como se habrá dado cuenta, eso no puede funcionar.
En su lugar, trate la base de datos más como un archivo de guardado actualizado automáticamente: actualiza la base de datos solo ocasionalmente, como cuando los jugadores inician o cierran sesión o se mueven de una zona a otra, o cada vez que sucede algo importante que no desea ser perdido en caso de un bloqueo del servidor.
Los servidores del juego deben mantener el estado mundial real en tiempo real, en la memoria, como en su ejemplo original. Ahora, el truco para el escalado horizontal es que no todos los servidores necesitan saber todo en cada momento . Por ejemplo, si el jugador A está jugando en la zona A en el servidor A, B servidor que ejecuta la zona B por lo general no necesita saber lo que el jugador A tiene en su mochila - y, si se hace necesario saber que por alguna razón (por ejemplo, debido a que el jugador B en la zona B lanza algún tipo de hechizo de espionaje remoto en A) solo puede pedir esa información al otro servidor .
Esto requiere que asigne responsabilidades claras a los servidores, de modo que cuando el servidor B quiera saber sobre la mochila del jugador A, sepa qué servidor tiene la información autorizada sobre eso. También es probable que desee incluir algún tipo de mecanismo de suscripción de actualización, de modo que, por ejemplo, el servidor B pueda decirle al servidor A " Tengo a alguien espiando al jugador A, manténgame informado sobre todo lo que hacen hasta que le diga lo contrario " . También queremos incluir algún tipo de sistema de transmisión global para eventos globales importantes que los jugadores puedan necesitar conocer sin importar dónde se encuentren; por supuesto, tales eventos también deberían registrarse en la base de datos, pero tenerlos transmitidos activamente a todos los servidores significa que los servidores no tendrán que seguir sondeando la base de datos para obtener actualizaciones.
fuente
Otras respuestas han hecho un buen trabajo al señalar cómo usar una base de datos, y no usar una base de datos para la comunicación. Otro aspecto que podría considerar es clasificar sus actualizaciones en función de cómo la información debe comunicarse a otras entidades. En lugar de establecer comunicación con los servidores, puede distribuir sus mensajes y utilizar mecanismos pubsub para comunicar actualizaciones entre entidades. Por ejemplo, puede tratar la ubicación de manera diferente en función de quién está cerca de usted:
Puede comunicar información de ubicación para una entidad escaneando periódicamente las entidades dentro del radio 2 * R (o algún múltiplo de eso en función de la velocidad de actualización y la velocidad máxima de una entidad), y suscribiendo la entidad a la alimentación de ubicación precisa o imprecisa de la otra entidad.
Podría tener diferentes estrategias para diferentes tipos de información, agrupar elementos comunes en las mismas colas de mensajes o tener diferentes colas para mensajes que necesitan ir a diferentes entidades (o simplemente enviarlas al conjunto más amplio de entidades y descartar los mensajes si No son útiles).
fuente