MemoryStoreService est un service de données à grande vitesse et faible latence qui fournit une sauvegarde de données rapide dans la mémoire accessible à partir de tous les serveurs dans une session en direct. Les stores de mémoire sont adaptés pour les données fréquentes et éphémères qui changent rapidement et ne nécessitent pas d'être durables, car elles sont plus rapides à accéder et à
Structures de données
Au lieu d'accéder directement aux données brutes, les magasins de mémoire ont trois structures de données primitives partagées sur les serveurs pour un traitement rapide : carte triée, Files d'attente, et carte de hachage. Chaque structure de données est une bonne pour certains cas d'utilisation :
- Matchmaking basé sur les compétences - Enregistrez les informations de l'utilisateur, telles que le niveau de compétence, dans une file d'attente partagée entre les serveurs et utilisez les serveurs du lobby pour exécuter le matchmaking périodiquement.
- Échange et vente entre serveurs - Activez le commerce universel entre différents serveurs, où les utilisateurs peuvent miser sur des articles avec des prix en temps réel, avec une carte triée de paires de valeur clé.
- Classements mondiaux - Store and update user rankings on a shared leaderboard inside a carte triée .
- Inventaires partagés - Enregistre les articles d'inventaire et les statistiques dans un inventaire partagé sur une carte de hachage partagée, où les utilisateurs peuvent utiliser les articles d'inventaire simultanément entre eux.
- Cache pour les données persistantes - Synchronisez et copiez vos données persistantes dans un magasin de données à une mémoire pour une performance améliorée. mape de hachage qui peut agir comme un cache et améliorer votre expérience.
En général, si vous avez besoin d'accéder à des données basées sur une clé spécifique, utilisez une carte de hachage. Si vous avez besoin que les données soient triées, utilisez une carte triée. Si vous avez besoin de traiter vos données dans un ordre spécifique, utilisez une file d'attente.
Limites et quotas
Pour maintenir la disponibilité et les performances du système, les magasins de mémoire ont des quotas d'utilisation des données pour la taille de la mémoire, les demandes d'API et la taille de la structure de données.
Les magasins de mémoire ont une politique d'expulsion basée sur le temps d'expiration, également appelée temps de vie (TTL). Les articles sont expulsés après leur expiration, et le quota de mémoire est libéré pour les nouvelles entrées. Lorsque vous atteignez la limite de mémoire, toutes les demandes d'écriture suivantes échouent jusqu'à ce que les articles expirent ou que vous les supprimiez manuellement.
Quote de taille de la mémoire
La limite de mémoire limite la quantité totale de mémoire que peut consommer une expérience. Ce n'est pas une valeur fixe. Au lieu de cela, il change au fil du temps en fonction du nombre d'utilisateurs dans l'expérience selon la formule suivante : 64KB + 1KB * [number of users] . La limite s'applique au niveau de l'expérience au lieu du niveau du serveur.
Lorsque les utilisateurs rejoignent l'expérience, le quota de mémoire supplémentaire est immédiatement disponible. Lorsque les utilisateurs quittent l'expérience, le quota ne se réduit pas immédiatement. Il y a une période de traçage de huit jours avant que le quota se réévalue à un niveau inférieur.
Après que votre expérience atteint la taille de la mémoire, tout ce qui est demandé en API qui augmente la taille de la mémoire échoue toujours. Les demandes qui réduisent ou ne modifient pas la taille de la mémoire réussissent toujours.
Avec le tableau de bord observabilité, vous pouvez afficher la taille de la mémoire en temps réel en utilisant le utilisation de la mémoire graphique.
Limites de demande d'API
Pour les limites de demande d'API, il y a une limite de demande d'unité qui s'applique à toutes les appels d'API de MemoryStoreService. Le quota est 1000 + 100 * [number of concurrent users] unités de demande par minute.
La plupart des appels d'API ne consomment qu'une unité de demande, avec quelques exceptions :
MemoryStoreSortedMap:GetRangeAsync()
Consomme des unités en fonction du nombre d'objets retournés. Par exemple, si cette méthode renvoie 10 articles, l'appel compte comme 10 unités de demande. Si elle renvoie une réponse vide, elle compte comme une unité de demande.
Consomme des unités basées sur le nombre d'objets retournés, comme MemoryStoreSortedMap:GetRangeAsync(), mais consomme une unité supplémentaire toutes les 2 secondes pendant la lecture. Spécifiez le temps de lecture maximum avec le paramètre waitTimeout.
MemoryStoreHashMap:UpdateAsync()
Consomme au moins deux unités.
MemoryStoreHashMap:ListItemsAsync()
Consomme [number of partitions scanned] + [items returned] unités.
La limite de demandes s'applique également au niveau de l'expérience au lieu du niveau du serveur. Cela fournit de la flexibilité pour distribuer les demandes parmi les serveurs tant que le taux de demande total ne dépasse pas le quota. Si vous dépassez le quota, vous recevez une réponse d'erreur lorsque le service limite vos demandes.
Avec la fonctionnalité observabilité disponible, vous pouvez afficher le quota de l'unité de demande de votre expérience en temps réel.
Limites de taille de la structure des données
Pour une seule carte ou file d'attente triée, les limites de taille et d'objets suivantes s'appliquent :
- Nombre max d'articles : 1 000 000
- Taille maximale totale (y compris les clés pour la carte triée) : 100 MB
Limites par partie
Voir Limites par partie .
Meilleures pratiques
Pour garder votre schéma d'utilisation de la mémoire optimale et éviter de frapper les limites, suivez ces meilleures pratiques :
Retirez les articles traités. Nettoyez coûteusement les éléments lus en utilisant la méthode MemoryStoreQueue:RemoveAsync() pour les queues et MemoryStoreSortedMap:RemoveAsync() pour les cartes triées peut libérer de la mémoire et garder la structure des données à jour.
Définir le temps d'expiration au plus petit cadre de temps possible lors de l'ajout de données. Bien que le temps d'expiration par défaut soit 45 jours pour les MemoryStoreQueue:AddAsync() et MemoryStoreSortedMap:SetAsync(), le paramètre de temps le plus court peut automatiquement nettoyer les données anciennes pour les empêcher de remplir votre quota de mémoire.
- Ne stockez pas une grande quantité de données avec une longue expiration, car cela risque d'excéder votre quota de mémoire et de potentiellement causer des problèmes qui peuvent interrompre toute votre expérience.
- Supprimez toujours des éléments inutiles ou définissez une expiration d'objet courte.
- Dans l'ensemble, vous devriez utiliser l'exclusion explicite pour libérer de la mémoire et l'expiration des éléments comme un mécanisme de sécurité pour empêcher les articles inutilisés de prendre de la mémoire pendant une période de temps étendue.
Ne conservez que les valeurs nécessaires en mémoire.
Par exemple, pour une expérience de maison d'拍卖, vous n'avez besoin de maintenir que le plus haut bid. Vous pouvez utiliser MemoryStoreQueue:UpdateAsync() sur une seule touche pour garder le plus haut bid plutôt que de garder tous les bid dans votre structure de données.
Utilisez l'exposition arrière exponentielle pour aider à rester en dessous des limites de demande API.
Par exemple, si vous recevez une DataUpdateConflict, vous pourriez essayer à nouveau après deux secondes, puis quatre, huit, etc. au lieu d'envoyer constamment des demandes à Class.MemoryStoreService pour obtenir la bonne réponse.
Divise les géantes structures de données en plusieurs plus petits par éclatement .
Il est souvent plus facile de gérer les données dans de plus petites structures plutôt que de stocker tout dans une seule grande structure de données. Cette approche peut également aider à éviter les limites d'utilisation et les taux. Par exemple, si vous avez une carte triée qui utilise des préfixes pour ses clés, considérez la séparation de chaque préfixe dans sa propre carte triée. Pour une expérience extrêmement populaire, vous pourriez même séparer les utilisateurs en plusieurs cartes en fonction des derniers chiffres de leur ID utilisateur.
Comprendre les valeurs stockées.
Par exemple, envisagez d'utiliser l'algorithme LZW pour réduire la taille de la valeur stockée.
Observabilité
La tableau de bord de l'observabilité fournit des informations et des analyses sur la surveillance et le débogage de votre utilisation de la mémoire. Avec des mises à jour en temps réel sur différents aspects de votre utilisation de la mémoire et des demandes d'API, vous pouvez suivre le schéma d'utilisation de la mémoire de votre expérience, afficher les quotas attribués en temps réel et suivre le statut de l'API et identifier les problèmes potentiels pour l'optimisation des performances.
Le tableau suivant liste et décrit tous les codes de statut des réponses d'API disponibles sur le tableau de bord de l'observabilité et le tableau de bord des demandes par API x état. Pour plus d'informations sur la façon de résoudre ces erreurs, voir Troubleshooting. Pour le quota ou la limite spécifiques que chaque erreur affecte, voir 2>Limits and Qu
Code d'état | Description |
---|---|
Succès | Succès. |
Limite de mémoire de données | Dépasse la limite de taille de la mémoire de niveau de structure des données (100 MB). |
Mise à jour de conflit | Conflit en raison de la mise à jour conjointe. |
Accès refusé | Impossible d'accéder aux données de l'expérience. Cette demande ne consomme pas d'unités de demande ou d'utiliser le quota. |
Erreur interne | Erreur interne. |
Demande non valide | La demande n'a pas les informations requises ou a des informations mal formées. |
Limite d'objets de structure de données | Dépasse la limite de niveau de structure de données (1M). |
Aucun élément trouvé | Aucun élément trouvé dans MemoryStoreQueue:ReadAsync() ou MemoryStoreSortedMap:UpdateAsync(). ReadAsync() polles toutes les 2 secondes et renvoie ce code de statut jusqu'à ce qu'il trouve des éléments dans la file d'attente. |
Limite de demandes de données | Dépasse la limite de niveau de requête de la structure des données (100 000 unités de requête par minute). |
Limite de demandes de partition | Dépasse la limite de demande de partie. |
Limite de demandes totales | Dépasse la limite de niveau de requête de l'univers. |
Limite de mémoire totale | Dépasse le quota de mémoire au niveau de l'univers. |
Taille de valeur de l'article trop grande | La taille de la valeur dépasse la limite (32KB). |
La table suivante liste les codes côté client, qui ne sont actuellement pas disponibles sur le tableau de bord de l'observabilité.
Code d'état | Description |
---|---|
Erreur interne | Erreur interne. |
Lieu non publié | Vous devez publier cet endroit pour utiliser le service de stockage de mémoire. |
Accès client non valide | MemoryStoreService doit être appelé depuis le serveur. |
ExpirationTime non valide | Le temps d'expiration du champ « expiration » doit être entre 0 et 3 888 000. |
Demande non valide | Impossible de convertir la valeur en JSON. |
Demande non valide | Impossible de convertir sortKey en un nombre ou une chaîne valide. |
Échec de la transformation de rappel | Échec de l'invocation de la fonction de rappel de transformation. |
Demande accélérée | Les demandes de stockage de mémoire récentes ont touché un ou plusieurs limites. |
Mise à jour du conflit | Nombre de tentatives maximum dépassé. |
Débogage
Le tableau suivant liste et décrit la solution recommandée pour chaque code de statut de réponse :
Erreur | Options de débogage |
---|---|
DataStructureCommands / PartitionCommands |
|
Limite de demandes totales | |
Limite d'objets de structure de données |
|
Limite de mémoire de données | |
Limite de mémoire totale | |
Mise à jour de conflit | implémentez un délai court entre les demandes pour éviter que plusieurs demandes se chargent en même temps. Pour les cartes triées, utilisez la fonction de rappel sur le Class.MemoryStoreSortedMap:Update |
Erreur interne |
. . |
Demande non valide |
|
Taille de valeur de l'article trop grande |
|
Tester et déboguer dans Studio
Les données dans MemoryStoreService sont isolées entre Studio et la production, afin que le changement des données dans Studio n'affecte pas le comportement de production. Cela signifie que vos appels d'API à partir de Studio n'accèdent pas aux données de production, ce qui vous permet de tester en toute sécurité les magasins de mémoire et de nouvelles fonctionnalités avant d'aller en production.
Les tests Studio ont les mêmes limites et quotas que la production. Pour les quotas calculés en fonction du nombre d'utilisateurs, le quota résultant peut être très petit, car vous êtes le seul utilisateur pour Studio testing. Lors du test à partir de Studio, vous remarquerez également une légère augmentation de la latence et des taux d'erreur plus élevés par rapport à l'utilisation dans la production en raison de quelques vérifications supplémentaires qui sont effectuées pour vérifier l'accès et les permissions.
Pour plus d'informations sur la façon de déboguer un stockage de mémoire dans les expériences en direct ou lors du test dans le studio, utilisez Console du développeur.