MemoryStoreService es un servicio de datos de alto rendimiento y bajo rendimiento que proporciona almacenamiento de datos rápido en el modo de memoria para acceder a todos los servidores en una sesión en vivo. Los almacenes de memoria son adecuados para datos frecuentes y epímeros que cambian rápidamente y no necesitan ser duraderos, porque son más ráp
Estructuras de datos
En lugar de acceder directamente a los datos sin procesar, las estructuras de datos compartidas tienen tres estructuras de datos primitivas compartidas entre los servidores para un procesamiento rápido: ordenar mapa, cola y mapa de hash. Cada estructura de datos es adecuada para algunos casos de uso:
- Matchmaking basado en habilidades - Guarda información del usuario, como el nivel de habilidad, en una cola compartida entre servidores, y usa los servidores de lobby para ejecutar el matchmaking periódicamente.
- Comercio y subastas entre servidores - Habilita el comercio universal entre diferentes servidores, donde los usuarios pueden realizar apuestas en artículos con precios que cambian en tiempo real, con un ordenado mapa de pares de valores clave.
- Tablas de clasificación globales - Almacena y actualiza las clasificaciones de usuarios en una tabla de clasificación compartida dentro de un mapa ordenado .
- Inventarios compartidos - Guardar artículos de inventario y estadísticas en un mapa de hash compartido , donde los usuarios pueden utilizar artículos de inventario concurrentemente entre sí.
- Almacenamiento para datos persistentes - Sincroniza y copia tus datos persistentes en un almacén de datos a un almacén de memoria hash map que puede actuar como un almacén y mejorar el ejecuciónde tu experiencia.
En general, si necesita acceder a datos basados en una clave específica, use un mapa de hash. Si necesita que esos datos sean ordenados, use un mapa ordenado. Si necesita procesar sus datos en un orden específico, use una cola.
Límites y Cuotas
Para mantener la escalabilidad y el ejecuciónsistema, las tiendas de memoria tienen cuotas de uso de datos para el tamaño de la memoria, las solicitudes de API y el tamaño de la estructura de datos.
Las tiendas de memoria tienen una política de expulsión basada en el tiempo de caducidad, también conocida como tiempo de vida (TTL). Los elementos se expulsan después de que caduquen, y la cuota de memoria se libera para las nuevas entradas. Cuando golpeas el límite de memoria, todas las solicitudes de escritura siguientes fallan hasta que los elementos caduquen o los eliminas manualmente.
Cuota de tamaño de memoria
El límite de memoria limita la cantidad total de memoria que puede consumir una experiencia. No es un valor fijo. En cambio, cambia con el tiempo dependiendo del número de usuarios en la experiencia según la siguiente fórmula: 64KB + 1KB * [number of users] . El límite se aplica en el nivel de la experiencia en lugar del nivel del servidor.
Cuando los usuarios se unen a la experiencia, la cuota de memoria adicional está disponible inmediatamente. Cuando los usuarios dejan la experiencia, la cuota no se reduce inmediatamente. Hay un período de seguimiento de ocho días antes de que la cuota reevaluada a un valor más bajo.
Después de que tu experiencia alcance el límite de tamaño de memoria, cualquier solicitud de API que aumente el tamaño de memoria siempre falla. Las solicitudes que reducen o no cambian el tamaño de memoria siempre tienen éxito.
Con el panel de observabilidad, puede ver el tamaño de memoria de su experiencia en tiempo real con la ayuda de la gráfica de uso de memoria.
Límites de solicitudes de API
Para los límites de solicitudes de API, hay una solicitud de unidad cuota que se aplica a todas las llamadas de API de MemoryStoreService. La cuota es 1000 + 100 * [número de usuarios concurrentes] solicitudes de unidades por minuto.
La mayoría de las llamadas de API solo consumen una unidad de solicitud, con algunas excepciones:
MemoryStoreSortedMap:GetRangeAsync()
Consume unidades basado en el número de artículos devueltos. Por ejemplo, si este método devuelve 10 artículos, la llamada cuenta como 10 unidades de solicitud. Si devuelve una respuesta vacía, cuenta como una solicitud de un solo artículo.
Consume unidades basadas en el número de artículos devueltos, justo como MemoryStoreSortedMap:GetRangeAsync(), pero consume una unidad adicional cada dos segundos mientras se lee. Especifique el tiempo de máximo de lectura con el parámetro waitTimeout .
MemoryStoreHashMap:UpdateAsync()
Consume una unidad mínima de dos.
MemoryStoreHashMap:ListItemsAsync()
Consume [número de particiones escaneadas] + [artículos devueltos] unidades.
El límite de solicitudes también se aplica en el nivel de experiencia en lugar del nivel del servidor. Esto proporciona flexibilidad para asignar las solicitudes entre los servidores siempre que la tasa de solicitudes total no exceda el límite. Si excedes el límite, recibes una respuesta de error cuando el servicio limita tus solicitudes.
Con la 功能 de observabilidad disponible, puede ver el quórum de solicitudes de su experiencia en tiempo real.
Límites de tamaño de la estructura de datos
Para un solo mapa o cola clasificada, los siguientes límites de tamaño y de artículos aplican:
- Número máximo de artículos: 1,000,000
- Tamaño máximo total (incluyendo las llaves para el mapa ordenado): 100 MB
Límites de per- partition
Mejores Prácticas
Para mantener su patrón de uso de memoria óptimo y evitar golpear los límites, siga estas mejores prácticas:
Elimina los elementos procesados. Limpia consistentemente los elementos de lectura usando el método MemoryStoreQueue:RemoveAsync() para las colas y MemoryStoreSortedMap:RemoveAsync() para las mapas sorteadas pueden liberar memoria y mantener la estructura de datos actualizada.
Establezca el tiempo de expiración en el menor marco de tiempo posible al agregar datos. Aunque el tiempo de expiración predeterminado es 45 días para ambos MemoryStoreQueue:AddAsync() y MemoryStoreSortedMap:SetAsync() , estableciendo el tiempo más corto posible puede limpiar automáticamente los datos antiguos para evitar que se llenen de memoria.
- No almacene una gran cantidad de datos con una fecha de caducidad larga, ya que riesga exceder su cuota de memoria y potencialmente causar problemas que pueden romper toda su experiencia.
- Elimina siempre los elementos no necesarios o establece una breve expiración de los elementos.
- En general, debe usar eliminación explícita para liberar memoria y la expiración de los elementos como un mecanismo de seguridad para evitar que se ocupen memoria por un período de tiempo extendido.
Solo se guardan los valores necesarios en el memoria.
Por ejemplo, para una experiencia de casa de subastas, solo necesitas mantener el máximo límite de ofertas. Puedes usar MemoryStoreQueue:UpdateAsync() en una llave para mantener el máximo límite de ofertas en tu estructura de datos.
Usa expresiones de rechazo exponenciales para ayudar a mantenerse por debajo de los límites de solicitudes de API.
Por ejemplo, si recibes un DataUpdateConflict, puede intentarlo después de dos segundos, luego cuatro, ocho, etc. en lugar de enviar solicitudes constantemente a MemoryStoreService para obtener la respuesta correcta.
Divide las estructuras de datos gigantes en múltiples más pequeñas por sharding .
A menudo es más fácil administrar los datos en estructuras más pequeñas que almacenar todo en una sola estructura de datos grande. Esta aproximación también puede ayudar a evitar los límites de uso y tasa. Por ejemplo, si tiene un mapa ordenado que usa prefijos para sus claves, considere separar cada prefijo en su propio mapa ordenado. Para una experiencia popular especialmente popular, puede incluso separar a los usuarios en múltiples mapas según los últimos dígitos de sus ID de usuario.
Compres los valores almacenados.
Por ejemplo, considere usar el algoritmo LZW para reducir el tamaño del valor almacenado.
Observabilidad
El Panel de Observabilidad proporciona informes y análisis de seguimiento para monitorear y solucionar problemas con el almacenamiento de tu memoria. Con gráficos de actualización en tiempo real en diferentes aspectos de tu uso de memoria y solicitudes de API, puedes rastrear el patrón de uso de memoria de tu experiencia, ver las cuotas asignadas actuales y monitorear el estado de la API y identificar posibles problemas para el rendimiento de optimización.
La siguiente tabla lista y describe todos los códigos de estado de las respuestas de API disponibles en el Panel de Observabilidad's Request Count by Status y Requests by API x Status gráficos. Para obtener más información sobre cómo resolver estos errores, see Troubleshooting . Para la cuota o límite específicos que se relacionan con un error, see 1> Límites y
Código de estado | Descripción |
---|---|
Éxito | Éxito. |
Límite de memoria de datos | Excede el límite de tamaño de memoria de nivel de estructura de datos (100MB). |
Actualización de Conflicto de Datos | Conflicto debido a una actualización concurrent. |
Acceso Denegado | No se puede acceder a los datos de la experiencia. Esta solicitud no consume unidades de solicitud o usa el quórum. |
Error interno | Error interno. |
Solicitud no válida | La solicitud no tiene la información requerida o tiene información malformada. |
Límite de estructura de datos | Excede el límite de nivel de la estructura de datos (1M). |
No se ha encontrado ningún artículo. | No se ha encontrado ningún artículo en MemoryStoreQueue:ReadAsync() o MemoryStoreSortedMap:UpdateAsync(). ReadAsync() realiza encuestas cada 2 segundos y devuelve este código de estado hasta que encuentra elementos en la cola. |
Límite de solicitudes de datos | Excede el límite de solicitudes de nivel de datos (100,000 solicitudes por minuto). |
Límite de solicitudes de partición | Excede el límite de solicitudes de unidad de partición. |
Límite de solicitudes | Excede el límite de unidad de solicitud a nivel de universo. |
Límite de memoria total | Excede el límite de memoria a nivel de universo. |
Demasiado grande para valores de artículos | El tamaño de valor supera el límite (32KB). |
La siguiente tabla lista los códigos de estado del lado del cliente, que actualmente no están disponibles en el Panel de Observabilidad.
Código de estado | Descripción |
---|---|
Error interno | Error interno. |
Lugar no publicado | Debes publicar este lugar para usar el servicio de almacenamiento de memoria. |
Acceso de cliente no válido | MemoryStoreService debe ser llamado desde el servidor. |
Tiempo de caducidad no válido | El tiempo de caducidad debe estar entre 0 y 3,888,000. |
Solicitud no válida | No se puede convertir el valor en JSON. |
Solicitud no válida | No se puede convertir sortKey en un número o cadena válidos. |
Transformación de llamada fallida | No se pudo invocar la función de llamada de transformación. |
Solicitud acelerada | Las solicitudes de almacenamiento de memoria reciente golpearon uno o más límites. |
Actualizar Conflicto | Has alcanzado el máximo de intentos. |
Solucionando problemas
La siguiente tabla lista y describe la solución recomendada para cada código de estado de respuesta:
Error | Opciones de solución de problemos |
---|---|
DataStructureCommands / PartitionCommands |
|
Límite de solicitudes | |
Límite de estructura de datos |
|
Límite de memoria de datos | |
Límite de memoria total | |
Actualización de Conflicto de Datos | Implantar un corto retraso entre las solicitudes para evitar múltiples solicitudes que actualizan la misma clave en el mismo tiempo. Para las mapas ordenadas, usa la función de llamada de Class.MemoryStoreService para eliminar elementos de la memoria del modo más eficiente posible. Para las mapas ordenadas, usa la función de llamada de |
Error interno |
0>bug0> que describe el problema con el ID de universo de su experiencia. |
Solicitud no válida |
|
Demasiado grande para valores de artículos |
|
Pruebas y diagnóstico en Studio
Los datos en MemoryStoreService están aislados entre Studio y la producción, por lo que cambiar los datos en Studio no afecta el comportamiento de producción. Esto significa que sus llamadas de API desde Studio no acceden a los datos de producción, lo que le permite probar con seguridad los almacenes de memoria y las nuevas características antes de pasar a la producción.
La prueba de Studio tiene los mismos límites y cuotas que la producción. Para las cuotas calculadas en función del número de usuarios, la cuota resultante puede ser muy pequeña, ya que eres el único usuario para Studio testing. Cuando pruebas desde Studio, también podrías notar una latencia más alta y tasas de error elevadas en comparación con el uso en producción debido a algunos controles adicionales que se realizan para verificar el acceso y las autorizaciones.
Para obtener información sobre cómo debug un almacén de memoria en experiencias en vivo o al probar en el estudio, usa Consola de Desarrollador.