MemoryStoreService è un servizio di dati ad alto throughput e bassa latenza che fornisce un rapido storage di dati in memoria accessibile da tutti i server in una Sessionedal vivo. Magazzini di memoria sono adatti per dati frequenti e temporanei che cambiano rapidamente e non hanno bisogno di essere duraturi, perché sono più veloci da accedere e scompaiono quando raggiungono la durata massima.Per i dati che devono persistere attraverso le sessioni, usa negozi di dati.
Strutture di dati
Invece di accedere direttamente ai dati grezzi, i depositi di memoria hanno tre strutture di dati primitive condivise tra i server per una rapida elaborazione: mappa ordinata , coda e mappa di hash .Ogni struttura di dati è una buona soluzione per determinati casi d'uso:
- Matchmaking basato sulle competenze - Salva le informazioni sull'utente, come il Livellodi abilità, in una coda condivisa tra i server e usa i server della lobby per eseguire il matchmaking periodicamente.
- Trading e aste cross-server - Abilita il trading universale tra diversi server, in cui gli utenti possono fare offerte su oggetti con prezzi in tempo reale che cambiano, con una mappa di coppie chiave-valore ordinata.
- Classifiche globali - Archivia e aggiorna i ranking degli utenti su una classifica condivisa all'interno di una mappa ordinata.
- Inventari condivisi - Salva oggetti di inventario e statistiche in una mappa di hash condivisa, in cui gli utenti possono utilizzare gli oggetti di inventario contemporaneamente l'uno con l'altro.
- Memoria di cache per dati persistenti - Sincronizza e copia i tuoi dati persistenti in un archivio di memoria mappa di hash che può agire come cache e migliorare le Prestazionedel tuo esperienza.
In Generale, se devi accedere ai dati in base a una chiave specifica, usa una mappa hash.Se hai bisogno che quei dati siano ordinati, usa una mappa ordinata.Se devi elaborare i dati in un ordine specifico, usa una coda.
Limiti e quote
Per mantenere la scalabilità e le Prestazionedel sistema, i depositi di memoria hanno quote di utilizzo dei dati per la dimensione della memoria, le richieste API e la dimensione della struttura dei dati.
I negozi di memoria hanno una politica di espulsione basata sul tempo di scadenza, noto anche come tempo di vita (TTL).Gli oggetti vengono sfrattati dopo che scadono e la quota di memoria viene liberata per nuovi ingressi.Quando raggiungi il limite di memoria, tutte le successive richieste di scrittura falliscono fino a quando gli elementi non scadono o li elimini manualmente.
Quota di dimensione della memoria
La quota di memoria limita la quantità totale di memoria che un'esperienza può consumare.Non è un valore fisso.Invece, cambia nel tempo a seconda del numero di utenti nell'esperienza secondo la seguente formula: 64KB + 1KB * [number of users] .La quota si applica al livello dell'esperienza invece del Livellodel server.
Quando gli utenti si uniscono all'esperienza, la quota di memoria aggiuntiva è disponibile immediatamente.Quando gli utenti lasciano l'esperienza, la quota non diminuisce immediatamente.C'è un periodo di ritorno alla base di otto giorni prima che la quota venga rivalutata a un valore più basso.
Dopo che la tua esperienza raggiunge la quota di dimensione della memoria, tutte le richieste API che aumentano la dimensione della memoria falliscono sempre.Le richieste che diminuiscono o non cambiano la dimensione della memoria hanno ancora successo.
Con la dashboard osservabilità, puoi visualizzare la quota di dimensione della memoria della tua esperienza in tempo reale utilizzando la tabella utilizzo della memoria .
Limiti delle richieste API
Per i limiti delle richieste API, c'è una quota di unità di richiesta che si applica a tutte le chiamate API MemoryStoreService.La quota è 1000 + 100 * [number of concurrent users] unità di richiesta per minuto.
La maggior parte delle chiamate API consuma solo una unità di richiesta, con alcune eccezioni:
MemoryStoreSortedMap:GetRangeAsync()
Consuma unità in base al numero di oggetti restituiti.Ad esempio, se questo metodo restituisce 10 elementi, la chiamata conta come 10 unità di richiesta.Se restituisce una risposta vuota, conta come una unità di richiesta.
Consuma unità in base al numero di oggetti restituiti, proprio come MemoryStoreSortedMap:GetRangeAsync() , ma consuma un'unità aggiuntiva ogni due secondi durante la lettura.Specifica il tempo di lettura massimo con il parametro waitTimeout.
MemoryStoreHashMap:UpdateAsync()
Consuma un minimo di due unità.
MemoryStoreHashMap:ListItemsAsync()
Consuma [number of partizioni scansionate] + [oggetti restituiti] unità.
La quota delle richieste viene applicata anche sul livello dell'esperienza invece del Livellodel server.Questo fornisce flessibilità per assegnare le richieste tra i server finché il tasso totale delle richieste non superi la quota.Se superi la quota, ricevi una risposta di errore quando il servizio limita le tue richieste.
Con la funzione osservabilità disponibile, puoi visualizzare la quota di richiesta dell'unità della tua esperienza in tempo reale.
Limiti della dimensione della struttura dei dati
Per una singola mappa o coda ordinata, si applicano i seguenti limiti di dimensione e numero di oggetti:
- Numero massimo di oggetti: 1,000,000
- Dimensione massima totale (incluse le chiavi per la mappa ordinata): 100 MB
Limiti per partizione
Vedi limiti per partizione.
Migliori pratiche
Per mantenere il modello di utilizzo della memoria ottimale e evitare di superare i limiti, segui queste migliori pratiche:
Rimuovi gli elementi elaborati.: Pulire in modo coerente gli elementi letti utilizzando il metodo MemoryStoreQueue:RemoveAsync() per le code e MemoryStoreSortedMap:RemoveAsync() per le mappe ordinate può liberare memoria e mantenere la struttura dei dati aggiornata.
Imposta il tempo di scadenza al più piccolo periodo di tempo possibile quando aggiungi dati.: Anche se il tempo di scadenza predefinito è di 45 giorni per entrambi MemoryStoreQueue:AddAsync() e MemoryStoreSortedMap:SetAsync(), impostare il tempo più breve possibile può pulire automaticamente i dati vecchi per impedire loro di riempire la quota di utilizzo della memoria.
- Non memorizzare una grande quantità di dati con una scadenza lunga, poiché rischia di superare la quota di memoria e potrebbe causare problemi che possono rompere l'intera esperienza.
- Sia sempre di eliminare esplicitamente gli oggetti non necessari o impostare una scadenza breve per gli oggetti.
- Generalmente, dovresti usare l'eliminazione esplicita per rilasciare la memoria e la scadenza degli oggetti come meccanismo di sicurezza per impedire agli oggetti non utilizzati di occupare memoria per un periodo di tempo esteso.
Conserva solo i valori necessari in memoria.
Ad esempio, per un'esperienza di casa d'aste, devi mantenere solo l'offerta più alta.Puoi usare MemoryStoreSortedMap:UpdateAsync() su una chiave per mantenere l'offerta più alta piuttosto che mantenere tutte le offerte nella tua struttura di dati.
Usa il ritiro esponenziale per aiutare a rimanere al di sotto dei limiti delle richieste API.
Ad esempio, se ricevi un DataUpdateConflict, potresti riprovare dopo due secondi, quindi quattro, otto, ecc.invece di inviare costantemente richieste a MemoryStoreService per ottenere la risposta corretta.
Dividi le strutture di dati giganti in più piccole da sharding .
Spesso è più facile gestire i dati in strutture più piccole piuttosto che memorizzare tutto in una grande struttura di dati.Questo approccio può anche aiutare a evitare limiti di utilizzo e tasso.Ad esempio, se hai una mappa ordinata che utilizza prefissi per le sue chiavi, considera di separare ciascun prefisso in una sua mappa ordinata separata.Per un'esperienza particolarmente popolare, potresti persino separare gli utenti in più mappe in base agli ultimi numeri dei loro ID utente.
Comprima i valori memorizzati.
Ad esempio, considera di utilizzare l'algoritmo LZW per ridurre la dimensione del valore memorizzato.
Osservabilità
La Dashboard dell'osservabilità fornisce insight e analisi per il monitoraggio e la risoluzione dei problemi dell'utilizzo del tuo archivio di memoria.Con grafici di aggiornamento in tempo reale su diversi aspetti dell'utilizzo della memoria e delle richieste API, puoi tracciare il modello di utilizzo della memoria della tua esperienza, visualizzare le quote allocate attuali, monitorare lo Statodell'API e identificare potenziali problemi per l'ottimizzazione delle prestazioni.
La seguente tabella elenca e descrive tutti i codici di stato delle risposte API disponibili sul grafico Conteggio richieste per stato e Richieste da API x Stato della dashboard di osservabilità.Per maggiori informazioni su come risolvere questi errori, vedi Risoluzione dei problemi.Per la quota o il limite specifico a cui si riferisce un errore, vedi Limiti e quote.
Codice di codice | Descrizione |
---|---|
Successo | Successo. |
Memoria di struttura dati oltre il limite | Supera il limite della dimensione della memoria della struttura dei dati (100MB). |
Conflicto di aggiornamento dei dati | Conflitto dovuto all'aggiornamento Aggiornarmento. |
Accesso negato | Non autorizzato ad accedere ai dati dell'esperienza. Questa richiesta non consuma unità di richiesta o utilizza la quota. |
Errore interno | Errore interno. |
Richiesta non valida | La richiesta non ha le informazioni richieste o ha informazioni malformate. |
Struttura datiItemOverLimit | Supera il limite del numero di elementi della struttura dei dati (1M). |
Nessun oggetto trovato | Nessun oggetto trovato in MemoryStoreQueue:ReadAsync() o MemoryStoreSortedMap:UpdateAsync() . ReadAsync() polls ogni 2 secondi e restituisce questo codice di stato fino a quando non trova oggetti nella coda. |
Richieste di struttura dati oltre il limite | Supera il limite di richiesta di livello della struttura dei dati (100.000 richieste all'ora). |
Partizione richieste overlimit | Supera il limite di richiesta di partizione. |
Richieste totali overlimit | Supera il limite di unità di richiesta a livello dell'universo. |
Memoria totale oltre limite | Supera la quota di memoria a livello dell'universo. |
ItemValueSizeTooLarge troppo grande | La dimensione del valore supera il limite (32KB). |
La seguente tabella elenca i codici di stato dal lato client, che al momento non sono disponibili sulla Dashboard dell'Osservabilità.
Codice di codice | Descrizione |
---|---|
Errore interno | Errore interno. |
Posto non pubblicato | Devi pubblicare questo luogo per utilizzare MemoryStoreService. |
Accesso client non valido | MemoryStoreService deve essere chiamato dal Server. |
Tempo di scadenza invalido | Il campo 'scadenza' deve essere tra 0 e 3,888,000. |
Richiesta non valida | Impossibile convertire il valore in json. |
Richiesta non valida | Impossibile convertire sortKey in un numero o una Stringavalida. |
TrasformCallbackFailed | Impossibile invocare la funzione di richiamo della trasformazione. |
RichiestaThrottled | Le richieste recenti di MemoryStores hanno superato uno o più limiti. |
Aggiorna conflitto | Superato il numero massimo di riprobi. |
Risoluzione dei problemi
La seguente tabella elenca e descrive la soluzione raccomandata per ciascun codice di stato di risposta:
Errore | Opzioni di risoluzione dei problemi |
---|---|
DataStructureRequestsOverLimit / PartitionRequestsOverLimit |
|
Richieste totali overlimit | |
Struttura datiItemOverLimit |
|
Memoria di struttura dati oltre il limite | |
Memoria totale oltre limite | |
Conflicto di aggiornamento dei dati |
Investiga per vedere se stai chiamando MemoryStoreService in modo efficiente per evitare i conflitti.Idealmente, non dovresti inviare troppe richieste.: Rimuovi costantemente gli elementi una volta letti utilizzando il metodo MemoryStoreQueue:RemoveAsync() per le code e MemoryStoreSortedMap:RemoveAsync() per le mappe ordinate. |
Errore interno |
|
Richiesta non valida |
|
ItemValueSizeTooLarge troppo grande |
|
Prova e debug in Studio
I dati in MemoryStoreService sono isolati tra Studio e produzione, quindi cambiare i dati in Studio non influisce sul comportamento di produzione.Questo significa che le chiamate API da Studio non hanno accesso ai dati di produzione, consentendoti di testare in sicurezza i depositi di memoria e le nuove funzionalità prima di passare alla produzione.
Il test dello studio ha gli stessi limiti e quote della produzione.Per le quote calcolate in base al numero di utenti, la quota risultante può essere molto piccola poiché sei l'unico utente per i test di Studio.Durante i test da Studio, potresti notare anche un leggero aumento della latenza e un aumento delle probabilità di errori rispetto all'uso in produzione a causa di alcuni controlli aggiuntivi che vengono eseguiti per verificare l'accesso e le autorizzazioni.
Per informazioni su come debuggare un archiviazione di memoria sulle esperienze dal vivo o durante i test in studio, usa Console dello sviluppatore.