MemoryStoreService es un servicio de almacenamiento de datos de alto rendimiento y baja latencia que proporciona un almacenamiento rápido en la memoria accesible desde todos los servidores en una sesión en vivo. Almacenes de memoria son adecuados para datos frecuentes y efímeros que cambian rápidamente y no necesitan ser duraderos, porque son más rápidos de acceder y desaparecen al alcanzar la vida útil máxima.Para los datos que deben persistir a través de sesiones, utilice tiendas de datos.
Estructuras de datos
En lugar de acceder directamente a los datos sin procesar, los almacenes de memoria tienen tres estructuras de datos primitivas compartidas entre servidores para un procesamiento rápido: mapa ordenado , cola y mapa de hash .Cada estructura de datos es una buena opción para ciertos casos de uso:
- Emparejamiento basado en habilidades - Guarde la información del usuario, como el nivel de habilidad, en una cola compartida entre los servidores, y use los servidores de lobby para ejecutar el emparejamiento periódicamente.
- Comercio y subasta entre servidores - Habilitar el comercio universal entre diferentes servidores, donde los usuarios pueden ofertar artículos con precios cambiantes en tiempo real, con un mapa ordenado de pares de clave-valor .
- Tablas de clasificación globales - Almacene y actualice las clasificaciones de usuarios en una tabla de clasificación compartida dentro de un mapa ordenado .
- Inventarios compartidos - Guarde elementos de inventario y estadísticas en un mapa compartido hash , donde los usuarios pueden utilizar elementos de inventario simultáneamente entre sí.
- Caché para datos persistentes - Sincroniza y copia tus datos persistentes en un almacén de datos a un almacén de memoria mapa de hash que puede actuar como caché 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 necesitas que esos datos se ordenen, usa un mapa ordenado.Si necesita procesar sus datos en un orden específico, use una cola.
Límites y cupos
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 expiración, también conocido como tiempo para vivir (TTL).Los elementos se expulsan después de que expiran, y la cuota de memoria se libera para nuevas entradas.Cuando alcanzas el límite de memoria, todas las solicitudes de escritura posteriores fallan hasta que expiren los artículos o los elimines manualmente.
Cuota de tamaño de memoria
El límite de memoria reduce la cantidad total de memoria que una experiencia puede consumir.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] .La cuota se aplica en el nivel de experiencia en lugar del nivel del servidor.
Cuando los usuarios se unen a la experiencia, la cuota de memoria adicional está disponible de inmediato.Cuando los usuarios abandonan la experiencia, la cuota no se reduce inmediatamente.Hay un período de seguimiento de ocho días antes de que la cuota se reevalúe a un valor más bajo.
Después de que tu experiencia alcance el límite de tamaño de memoria, todas las solicitudes de API que aumenten el tamaño de memoria siempre fallan.Las solicitudes que disminuyen o no cambian el tamaño de la memoria aún tienen éxito.
Con el tablero de observabilidad, puedes ver la cuota de tamaño de memoria de tu experiencia en tiempo real usando el gráfico de uso de memoria .
Límites de solicitudes de API
Para los límites de solicitudes de API, hay una cuota de unidad de solicitud que se aplica a todas las llamadas MemoryStoreService.La cuota es 1000 + 100 * [number of concurrent users] unidades de solicitud por minuto.
La mayoría de las llamadas de API solo consumen una unidad de solicitud, con algunas excepciones:
MemoryStoreSortedMap:GetRangeAsync()
Consume unidades basadas en el número de artículos devueltos.Por ejemplo, si este método devuelve 10 artículos, la llamada se cuenta como 10 unidades de solicitud.Si devuelve una respuesta vacía, cuenta como una unidad de solicitud.
Consume unidades basadas en el número de artículos devueltos, al igual que MemoryStoreSortedMap:GetRangeAsync() , pero consume una unidad adicional cada dos segundos mientras se lee.Specifica el tiempo de lectura máximo con el parámetro waitTimeout.
MemoryStoreHashMap:UpdateAsync()
Consume un mínimo de dos unidades.
MemoryStoreHashMap:ListItemsAsync()
Consume [número de particiones escaneadas] + [artículos devueltos] unidades.
La cuota 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 total de solicitudes no supere el límite.Si excedes la cuota, recibe una respuesta de error cuando el servicio restringe sus solicitudes.
Con la característica de observabilidad disponible, puedes ver la cuota de solicitudes de tu experiencia en tiempo real.
Límites de tamaño de la estructura de datos
Para un mapa o cola ordenada única, se aplican los siguientes límites de tamaño y número de artículos:
- Número máximo de artículos: 1,000,000
- Tamaño total máximo (incluyendo claves para mapa ordenado): 100 MB
Límites por partición
Mejores prácticas
Para mantener el patrón de uso de memoria óptimo y evitar alcanzar los límites , sigue estas mejores prácticas:
Eliminar artículos procesados.: Limpiar consistentemente los elementos leídos usando el método MemoryStoreQueue:RemoveAsync() para colas y MemoryStoreSortedMap:RemoveAsync() para mapas ordenados puede liberar memoria y mantener la estructura de datos actualizada.
Establece el tiempo de expiración al marco de tiempo más pequeño posible al agregar datos.: Aunque el tiempo de expiración predeterminado es de 45 días para ambos MemoryStoreQueue:AddAsync() y MemoryStoreSortedMap:SetAsync(), establecer el tiempo más corto posible puede limpiar automáticamente los datos antiguos para evitar que se llenen tu cuota de uso de memoria.
- No almacene una gran cantidad de datos con una larga expiración, ya que corre el riesgo de exceder su cuota de memoria y potencialmente causar problemas que puedan romper toda su experiencia.
- Siempre elimine explícitamente los elementos no necesarios o establezca una breve expiración de elementos.
- En general, debe usar la eliminación explícita para liberar la memoria y la expiración de artículos como mecanismo de seguridad para evitar que los artículos no utilizados ocupen memoria durante un período de tiempo extendido.
Solo mantenga los valores necesarios en memoria.
Por ejemplo, para una experiencia de casa de subastas, solo necesitas mantener la oferta más alta.Puedes usar MemoryStoreSortedMap:UpdateAsync() en una clave para mantener la oferta más alta en lugar de mantener todas las ofertas en tu estructura de datos.
Usa retroceso exponencial para ayudar a permanecer por debajo de los límites de solicitudes de API.
Por ejemplo, si recibes un DataUpdateConflict, puedes volver a intentarlo después de dos segundos, luego cuatro, ocho, etc.en lugar de enviar constantemente solicitudes a MemoryStoreService para obtener la respuesta correcta.
Divide las estructuras de datos gigantescas en múltiples más pequeñas por fragmentación.
A menudo es más fácil administrar los datos en estructuras más pequeñas en lugar de almacenar todo en una gran estructura de datos.Este enfoque también puede ayudar a evitar los límites de uso y tasa.Por ejemplo, si tienes un mapa ordenado que usa prefijos para sus claves, considera separar cada prefijo en su propio mapa ordenado.Para una experiencia especialmente popular, incluso puedes separar a los usuarios en múltiples mapas según los últimos dígitos de sus ID de usuario.
Comprima los valores almacenados.
Por ejemplo, considere usar el algoritmo LZW para reducir el tamaño del valor almacenado.
Observabilidad
El tablero de observabilidad proporciona insights y análisis para monitorear y solucionar problemas de uso de tu almacén de memoria.Con tablas de actualización en tiempo real sobre diferentes aspectos del uso de memoria y solicitudes de API, puedes rastrear el patrón de uso de memoria de tu experiencia, ver las cuotas asignadas actuales, monitorear el estado de la API y identificar posibles problemas para la optimización del rendimiento.
La siguiente tabla lista y describe todos los códigos de estado de las respuestas de la API disponibles en los gráficos Número de solicitudes por estado y Solicitudes por API x Estado del tablero de observabilidad.Para obtener más información sobre cómo resolver estos errores, vea Solución de problemas.Para la cuota o límite específico al que se refiere un error, vea Límites y cuotas.
códigode estado | Descripción |
---|---|
Éxito | Éxito. |
Límite de memoria de estructura de datos sobre el límite | Excede el límite de memoria de nivel de estructura de datos (100MB). |
Conflicto de actualización de datos | Conflicto debido a la actualización simultánea. |
Acceso denegado | No autorizado para acceder a los datos de experiencia. Esta solicitud no consume unidades de solicitud o utiliza cuota. |
Error interno | Error interno. |
Solicitud inválida | La solicitud no tiene la información requerida o tiene información malformada. |
ItemDataStructureOverLimit sobre el límite | Excede el límite de número de elementos de nivel de estructura de datos (1M). |
NoArtículoEncontrado | No se encontró 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 encuentre artículos en la cola. |
Solicitudes estructurales por encima del límite | Excede el límite de unidad de solicitud de nivel de estructura de datos (100,000 solicitudes por minuto). |
Solicitudes de partición sobre el límite | Excede el límite de solicitud de partición. |
Solicitudes totales sobre límite | Excede el límite de unidad de solicitud a nivel del universo. |
Memoria total por encima del límite | Excede el límite de memoria a nivel de universo. |
Tamaño de valor de artículo demasiado grande | El tamaño del valor supera el límite (32KB). |
La siguiente tabla lista los códigos de estado desde el lado del cliente, que actualmente no están disponibles en el tablero de observabilidad.
códigode estado | Descripción |
---|---|
Error interno | Error interno. |
Lugar no publicado | Debes publicar este lugar para usar MemoryStoreService. |
Acceso de cliente inválido | MemoryStoreService debe llamarse desde el servidor. |
Tiempo de expiración inválido | El tiempo de campo 'expiración' debe estar entre 0 y 3,888,000. |
Solicitud inválida | No se puede convertir el valor a json. |
Solicitud inválida | No se puede convertir sortKey a un número o cadena válos. |
TransformCallbackFailed | No se pudo invocar la función de llamada de transformación. |
Solicitud acelerada | Las solicitudes recientes de almacenes de memoria golpearon uno o más límites. |
Actualizar conflicto | Se superó el número máximo de intentos. |
Solucionar problemas
La siguiente tabla lista y describe la solución recomendada para cada código de estado de respuesta:
Errores | Opciones de solución de problemas |
---|---|
DataStructureRequestsOverLimit / PartitionRequestsOverLimit |
|
Solicitudes totales sobre límite | |
ItemDataStructureOverLimit sobre el límite |
|
Límite de memoria de estructura de datos sobre el límite | |
Memoria total por encima del límite | |
Conflicto de actualización de datos |
Investiga para ver si estás llamando MemoryStoreService de manera eficiente para evitar conflictos.Idealmente, no deberías enviar solicitudes en exceso.: Elimina consistentemente elementos una vez que sean leídos usando el método MemoryStoreQueue:RemoveAsync() para colas y MemoryStoreSortedMap:RemoveAsync() para mapas ordenados. |
Error interno |
|
Solicitud inválida |
|
Tamaño de valor de artículo demasiado grande |
|
Prueba y depura en Studio
Los datos en MemoryStoreService están aislados entre Studio y producción, por lo que cambiar los datos en Studio no afecta el comportamiento de producción.Esto significa que tus llamadas de API desde Studio no acceden a los datos de producción, lo que te permite probar con seguridad almacenamientos de memoria y nuevas funciones antes de pasar a la producción.
Las pruebas de estudio tienen 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 las pruebas de Studio.Al probar desde Studio, también podrías notar una latencia ligeramente mayor y una tasa de errores elevada en comparación con el uso en producción debido a algunas comprobaciones adicionales que se realizan para verificar el acceso y los permisos.
Para obtener información sobre cómo solucionar problemas con un almacén de memoria en experiencias en vivo o al probar en el estudio, use Consola de desarrollador.