En este documento se describen las prácticas recomendadas para usar Spanner como la base de datos de backend principal de almacenamiento del estado de los videojuegos. Puedes usar Spanner en lugar de bases de datos comunes para almacenar datos de autenticación e inventario de los jugadores. Este documento está dirigido a ingenieros de backend de videojuegos que trabajan en el almacenamiento de estados a largo plazo, así como a operadores y administradores de infraestructuras de videojuegos que admiten esos sistemas y quieren alojar su base de datos de backend enGoogle Cloud.
Los juegos multijugador y online han evolucionado hasta requerir estructuras de bases de datos cada vez más complejas para monitorizar los derechos, el estado y los datos de inventario de los jugadores. El aumento de las bases de jugadores y la creciente complejidad de los juegos han llevado a soluciones de bases de datos que son difíciles de escalar y gestionar, y que suelen requerir el uso de fragmentación o clustering. El seguimiento de objetos valiosos del juego o del progreso crítico de los jugadores suele requerir transacciones y es difícil de eludir en muchos tipos de bases de datos distribuidas.
Spanner es el primer servicio de base de datos escalable de categoría empresarial con coherencia inmediata y distribuido por todo el mundo que se ha creado específicamente para la nube. Así, combina las ventajas de la estructura de las bases de datos relacionales con la escalabilidad horizontal de las no relacionales. Muchas empresas de videojuegos han descubierto que es una solución adecuada para sustituir las bases de datos de autenticación y de estado de los juegos en sistemas a escala de producción. Puedes escalar para obtener más rendimiento o almacenamiento mediante laGoogle Cloud consola para añadir nodos. Spanner puede gestionar de forma transparente la replicación global con una coherencia sólida, por lo que no tendrás que gestionar réplicas regionales.
En este documento de prácticas recomendadas se tratan los siguientes temas:
- Conceptos importantes de Spanner y diferencias con las bases de datos que se suelen usar en los juegos.
- Cuándo es Spanner la base de datos adecuada para tu juego.
- Patrones que se deben evitar al usar Spanner en juegos.
- Diseñar las operaciones de la base de datos con Spanner como base de datos del juego.
- Modelizar los datos y crear un esquema para obtener el mejor rendimiento con Spanner.
Terminología
- Derechos
- Juegos, expansiones o compras en la aplicación que pertenezcan a un jugador.
- Información de identificación personal (IIP)
- En los juegos, la información suele incluir la dirección de correo electrónico y los datos de la cuenta de pago, como el número de la tarjeta de crédito y la dirección de facturación. En algunos mercados, esta información puede incluir un número de identificación nacional.
- Base de datos de juegos
- Una base de datos que contiene el progreso y el inventario de los jugadores de un juego.
- Base de datos de autenticación (base de datos de autenticación)
- Una base de datos que incluye los derechos de los jugadores y la información personal identificable que utilizan los jugadores al hacer una compra. La base de datos de autenticación también se conoce como base de datos de cuentas o base de datos de jugadores. Esta base de datos a veces se combina con la base de datos del juego, pero a menudo se separa en estudios o editores que tienen varios títulos.
- Transacción
- Una transacción de base de datos: un conjunto de operaciones de escritura que tienen un efecto de todo o nada. O bien la transacción se realiza correctamente y se aplican todas las actualizaciones, o bien la base de datos vuelve a un estado que no incluye ninguna de las actualizaciones de la transacción. En los juegos, las transacciones de bases de datos son más importantes cuando se procesan pagos y cuando se asigna la propiedad de inventario o moneda valiosos del juego.
- Sistema de gestión de bases de datos relacionales (RDBMS)
- Un sistema de base de datos basado en tablas y filas que se referencian entre sí. SQL Server, MySQL y (con menos frecuencia) Oracle® son ejemplos de bases de datos relacionales que se usan en juegos. Se usan con frecuencia porque pueden proporcionar metodologías conocidas y garantías sólidas sobre las transacciones.
- Base de datos NoSQL
- Bases de datos que no están estructuradas de forma relacional. Estas bases de datos son cada vez más populares en los juegos porque ofrecen mucha flexibilidad cuando cambia el modelo de datos. Entre las bases de datos NoSQL se incluyen MongoDB y Cassandra.
- Clave principal
- Normalmente, es la columna que contiene el ID único de los artículos del inventario, las cuentas de jugador y las transacciones de compra.
- Instancia
- Una sola base de datos. Por ejemplo, un clúster ejecuta varias copias del software de la base de datos, pero aparece como una sola instancia en el backend del juego.
- Node
- En este documento, se refiere a una sola máquina que ejecuta una copia del software de la base de datos.
- Réplica
- Una segunda copia de una base de datos. Las réplicas se usan con frecuencia para la recuperación de datos y la alta disponibilidad, o para aumentar el rendimiento de lectura.
- Clúster
- Varias copias del software que se ejecutan en muchos equipos que, en conjunto, se muestran como una sola instancia en el backend del juego. La agrupación en clústeres se usa para la escalabilidad y la disponibilidad.
- Fragmentación
- Una instancia de una base de datos. Muchos estudios de videojuegos ejecutan varias instancias de bases de datos homogéneas, cada una de las cuales contiene un subconjunto de los datos del juego. Cada una de estas instancias se denomina fragmento. El particionado se suele hacer para mejorar el rendimiento o la escalabilidad, lo que implica sacrificar la eficiencia de la gestión y aumentar la complejidad de la aplicación. La fragmentación en Spanner se implementa mediante divisiones.
- Dividir
- Spanner divide los datos en fragmentos llamados divisiones, donde las divisiones individuales pueden moverse de forma independiente entre sí y asignarse a diferentes servidores. Una división se define como un intervalo de filas de una tabla de nivel superior (es decir, no intercalada), donde las filas se ordenan por clave principal. Las claves de inicio y fin de este intervalo se denominan "límites de división". Spanner añade y elimina automáticamente límites de divisiones, lo que cambia el número de divisiones de la base de datos. Spanner divide los datos en función de la carga: añade límites de división automáticamente cuando detecta una carga de lectura o escritura alta repartida entre muchas claves de una división.
- Punto de acceso
- Cuando una sola división de una base de datos distribuida, como Spanner, contiene registros que reciben una gran parte de todas las consultas que se dirigen a la base de datos. Este escenario no es deseable porque reduce el rendimiento.
Usar Spanner en videojuegos
En la mayoría de los casos en los que te planteas usar un SGBDR para tu juego, Spanner es una opción adecuada porque puede sustituir de forma eficaz la base de datos del juego, la base de datos de autenticación o, en muchos casos, ambas.
Bases de datos de juegos
Spanner puede funcionar como una única autoridad transaccional mundial, lo que la convierte en una opción excelente para los sistemas de inventario de juegos. Cualquier moneda u objeto del juego que se pueda intercambiar, vender, regalar o transferir de otro modo de un jugador a otro supone un reto para los back-ends de juegos a gran escala. A menudo, la popularidad de un juego puede superar la capacidad de una base de datos tradicional para gestionar todo en una base de datos de un solo nodo. En función del tipo de juego, la base de datos puede tener problemas con el número de operaciones necesarias para gestionar la carga de jugadores, así como con la cantidad de datos almacenados. Esto suele llevar a los desarrolladores de juegos a fragmentar su base de datos para mejorar el rendimiento o a almacenar tablas que no paran de crecer. Este tipo de solución conlleva una complejidad operativa y unos costes de mantenimiento elevados.
Para mitigar esta complejidad, una estrategia habitual es ejecutar regiones de juego completamente independientes sin forma de mover datos entre ellas. En este caso, los jugadores de diferentes regiones de juego no pueden intercambiar objetos ni moneda, ya que los inventarios de cada región se almacenan en bases de datos independientes. Sin embargo, esta configuración sacrifica la experiencia de juego preferida en favor de la simplicidad operativa y de desarrollo.
Por otro lado, puedes permitir las transacciones entre regiones en una base de datos fragmentada geográficamente, pero a menudo con un coste de complejidad elevado. Esta configuración requiere que las transacciones abarquen varias instancias de la base de datos, lo que da lugar a una lógica compleja y propensa a errores en el lado de la aplicación. Intentar obtener bloqueos de transacciones en varias bases de datos puede tener un impacto significativo en el rendimiento. Además, no poder confiar en las transacciones atómicas puede provocar que los jugadores aprovechen vulnerabilidades, como la duplicación de monedas u objetos del juego, lo que perjudica el ecosistema y la comunidad del juego.
Spanner puede simplificar tu enfoque de las transacciones de inventario y de moneda. Incluso cuando se usa Spanner para almacenar todos los datos de tu juego en todo el mundo, ofrece transacciones de lectura y escritura con propiedades ACID (atomicidad, coherencia, aislamiento y durabilidad) aún más sólidas que las convencionales. Gracias a la escalabilidad de Spanner, los datos no tienen que fragmentarse en instancias de base de datos independientes cuando se necesita más rendimiento o almacenamiento. En su lugar, puedes añadir más nodos. Además, Spanner gestiona de forma transparente la alta disponibilidad y la resiliencia de los datos por los que los juegos suelen agrupar sus bases de datos, sin necesidad de configuración ni gestión adicionales.
Bases de datos de autenticación
Spanner también es una buena opción para las bases de datos de autenticación, sobre todo si quieres estandarizar un único RDBMS en tu estudio o a nivel de editor. Aunque las bases de datos de autenticación de los juegos no suelen requerir la escala de Spanner, las garantías transaccionales y la alta disponibilidad de datos pueden hacer que sea una opción atractiva. La replicación de datos en Spanner es transparente, síncrona e integrada. Spanner tiene configuraciones que ofrecen una disponibilidad del 99,99% ("cuatro nueves") o del 99,999% ("cinco nueves"), con "cinco nueves" correspondiente a menos de cinco minutos y medio de indisponibilidad al año. Este tipo de disponibilidad la convierte en una buena opción para la ruta de autenticación crítica que se requiere al principio de cada sesión del jugador.
Prácticas recomendadas
En esta sección se ofrecen recomendaciones sobre cómo usar Spanner en el diseño de juegos. Es importante modelar los datos de tu juego para aprovechar las funciones únicas que ofrece Spanner. Aunque puedes acceder a Spanner usando la semántica de las bases de datos relacionales, algunos puntos de diseño de esquemas pueden ayudarte a mejorar el rendimiento. En la documentación de Spanner se incluyen recomendaciones detalladas sobre el diseño de esquemas que puedes consultar, pero en las siguientes secciones se describen algunas prácticas recomendadas para las bases de datos de juegos.
Las prácticas que se describen en este documento se basan en las experiencias de los clientes y en casos prácticos.
Usar UUIDs como IDs de jugador y de personaje
La tabla de jugadores suele tener una fila por cada jugador y su moneda del juego, su progreso u otros datos que no se asignan fácilmente a filas discretas de la tabla de inventario. Si tu juego permite que los jugadores tengan partidas guardadas independientes para varios personajes, como muchos juegos multijugador masivos persistentes de gran tamaño, esta tabla suele contener una fila por cada personaje. El patrón es el mismo.
Te recomendamos que uses un identificador de personaje o jugador único a nivel mundial (ID de personaje) como clave principal de la tabla de personajes. También te recomendamos que uses el identificador único universal (UUID) v4, ya que distribuye los datos de los jugadores entre los nodos de la base de datos y puede ayudarte a mejorar el rendimiento de Spanner.
Usar el entrelazado en tablas de inventario
La tabla de inventario suele contener elementos del juego, como el equipo de los personajes, cartas o unidades. Normalmente, un jugador tiene muchos objetos en su inventario. Cada elemento se representa mediante una sola fila en la tabla.
Al igual que otras bases de datos relacionales, una tabla de inventario de Spanner tiene una clave principal que es un identificador único global del elemento, tal como se muestra en la siguiente tabla.
itemID
|
type
|
playerID
|
|---|---|---|
7c14887e-8d45 |
1 |
6f1ede3b-25e2 |
8ca83609-bb93 |
40 |
6f1ede3b-25e2 |
33fedada-3400 |
1 |
5fa0aa7d-16da |
e4714487-075e |
23 |
5fa0aa7d-16da |
d4fbfb92-a8bd |
14 |
5fa0aa7d-16da |
31b7067b-42ec |
3 |
26a38c2c-123a |
En la tabla de inventario de ejemplo, itemID y playerID se han truncado para que sean más fáciles de leer. Una tabla de inventario real también contendría muchas otras columnas que no se incluyen en el ejemplo.
Una práctica habitual en un RDBMS para hacer un seguimiento de la propiedad de los elementos es usar una columna como clave externa que contenga el ID del jugador propietario actual. Esta columna es la clave principal de una tabla de base de datos independiente. En Spanner, puedes usar el entrelazado, que almacena las filas de inventario cerca de la fila de la tabla de jugadores asociada para mejorar el rendimiento. Cuando uses tablas intercaladas, ten en cuenta lo siguiente:
- No puedes generar un objeto sin un propietario. Puedes evitar que haya objetos sin propietario en el diseño del juego si conoces la limitación con antelación.
Diseñar la indexación para evitar los puntos de acceso
Muchos desarrolladores de juegos implementan índices en muchos de los campos de inventario para optimizar determinadas consultas. En Spanner, al crear o actualizar una fila con datos en ese índice, se genera una carga de escritura adicional proporcional al número de columnas indexadas. Puedes mejorar el rendimiento de Spanner eliminando los índices que no se usen con frecuencia o implementando estos índices de otras formas que no afecten al rendimiento de la base de datos.
En el siguiente ejemplo, se muestra una tabla de registros de puntuaciones altas de jugadores a largo plazo:
CREATE TABLE Ranking (
PlayerID STRING(36) NOT NULL,
GameMode INT64 NOT NULL,
Score INT64 NOT NULL
) PRIMARY KEY (PlayerID, GameMode)
Esta tabla contiene el ID del jugador (UUIDv4), un número que representa un modo de juego, una fase o una temporada, y la puntuación del jugador.
Para acelerar las consultas que filtran por el modo de juego, considera el siguiente índice:
CREATE INDEX idx_score_ranking ON Ranking (
GameMode,
Score DESC
)
Si todos los jugadores juegan al mismo modo de juego llamado 1, este índice crea un punto de acceso
donde GameMode=1. Si quieres obtener una clasificación para este modo de juego, el índice solo analiza las filas que contienen GameMode=1, lo que permite devolver la clasificación rápidamente.
Si cambias el orden del índice anterior, puedes solucionar este problema del punto de acceso:
CREATE INDEX idx_score_ranking ON Ranking (
Score DESC,
GameMode
)
Este índice no creará un punto de acceso significativo a partir de los jugadores que compitan en el mismo modo de juego, siempre que sus puntuaciones se distribuyan en el intervalo posible. Sin embargo, obtener puntuaciones no será tan rápido como con el índice anterior, ya que la consulta analiza todas las puntuaciones de todos los modos para determinar si GameMode=1.
Por lo tanto, el índice reordenado resuelve el problema anterior del punto de acceso en el modo Juego, pero aún se puede mejorar, como se muestra en el siguiente diseño.
CREATE TABLE GameMode1Ranking (
PlayerID STRING(36) NOT NULL,
Score INT64 NOT NULL
) PRIMARY