MemoryStoreService è un servizio dati ad alta velocità e bassa latenza che fornisce una memoria dati veloce accessibile da tutti i server in una Sessionedal vivo. I magazzini di memoria sono adatti per i dati frequenti e epici che cambiano rapidamente e non hanno bisogno di essere persistenti, poiché sono più veloci da accedere e scompaiono quando raggiungono
Strutture di dati
Invece di accedere direttamente ai dati grezzi, le memorie condividono tre strutture di dati primitive tra i server per un elaborazione rapida: mappa ordinata , coda e mappa di hash. Ogni struttura di dati è adatta a casi d'uso specifici:
- Matchmaking basato sulla skill-based - Salva le informazioni dell'utente, come il Livellodi abilità, in una condivisa coda tra i server e usa i server della lobby per eseguire il matchmaking periodically.
- Cross-server trading and auctioning - Abilita il trading universale tra diversi server, in cui gli utenti possono bid on items with real-time changing prices, con a sort map of key-value pairs.
- Classifiche globali - memorizza e aggiorna i punteggi utente su una classifica condivisa all'interno di una mappa ordinata .
- Inventari condivisi - Salva gli oggetti dell'inventario e le statistiche in una mappa condivisa hash , in cui gli utenti possono utilizzare gli oggetti dell'inventario contemporaneamente tra di loro.
- Cache per dati persistenti - Sincronizza e copia i tuoi dati persistenti in un data store in un memoria store hash map che può agire come cache e migliorare le Prestazionedella tua esperienza.
In Generale, se devi accedere ai dati in base a una chiave specifica, usa una mappa di hashes. Se hai bisogno che i dati siano ordinati, usa una mappa sortita. Se hai bisogno di elaborare i tuoi dati in un ordine specifico, usa una coda.
Limitazioni e quotazioni
Per mantenere la scalabilità e le Prestazionedel sistema, le memorie 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, anche conosciuta come tempo per vivere (TTL). Gli elementi vengono espulsi dopo che scadono, e la quota di memoria viene liberata per nuovi ingressi. Quando si raggiunge il limite di memoria, tutte le richieste di scrittura successive falliscono fino all'esaurimento degli elementi o si eliminano manualmente.
Quota della dimensione della memoria
Il limite della 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] . Il limite si applica al livello dell'esperienza invece che al 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 si riduce immediatamente. C'è un periodo di tracciamento di otto giorni prima che la quota si valuti a un valore inferiore.
Dopo che la tua esperienza raggiunge la quota di dimensioni della memoria, qualsiasi richiesta API che aumenta le dimensioni della memoria non riesce mai. Le richieste che diminuiscono o non cambiano le dimensioni della memoria sono ancora in grado di eseguirsi.
Con la dashboard dell'osservabilità, puoi visualizzare la quota della memoria della tua esperienza in tempo reale utilizzando la memoria Usage chart.
Limitazioni richieste API
Per i limiti della richiesta API, c'è una unità di richiesta quota che si applica a tutte le chiamate API MemoryStoreService . La quota è 1000 + 100 * [number of concurrent users] richieste unità per minuto.
La maggior parte delle chiamate API consuma solo un'unità di richiesta, con alcune eccezioni:
MemoryStoreSortedMap:GetRangeAsync()
Consuma unità in base al numero di oggetti restituiti. Ad esempio, se questo metodo restituisce 10 oggetti, la chiamata conta come 10 unità di richiesta. Se restituisce una risposta vuota, conta come un'unità di richiesta.
Consuma unità basate sul numero di oggetti restituiti, come MemoryStoreSortedMap:GetRangeAsync() , ma consuma un'unità aggiuntiva ogni due secondi mentre si legge. Specify il tempo di lettura massimo con il parametro waitTimeout .
MemoryStoreHashMap:UpdateAsync()
Consuma almeno due unità.
MemoryStoreHashMap:ListItemsAsync()
Consuma [number of partitions scanned] + [items returned] unità.
La quota di richieste viene applicata anche al livello dell'esperienza invece che al Livellodel server. Ciò fornisce flessibilità per distribuire le richieste tra i server poiché il tasso di richieste totali non supera la quota. Se superi il quota, ricevi una risposta di errore quando il servizio limita le richieste.
Con la funzione osservabilità disponibile, puoi visualizzare la quota di richiesta dell'esperienza in tempo reale.
Limitazioni della dimensione dei dati
Per una singola mappa o coda ordinata, si applicano i seguenti limiti di dimensioni e di oggetti:
- Numero massimo di oggetti: 1,000,000
- Dimensione massima totale (incluse le chiavi per la mappa ordinata): 100 MB
Limitazioni per-пар티션
Vedi Limiti per- partition.
Migliori Pratiche
Per mantenere il tuo modello di utilizzo della memoria ottimale e evitare di colpire i limiti, segui queste migliori pratiche:
Rimuovi gli elementi elaborati. Pulisci coerentemente gli elementi di lettura usando il metodo MemoryStoreQueue:RemoveAsync() per le code e MemoryStoreSortedMap:RemoveAsync() per le mappe sortite. Può liberare la memoria e mantenere la struttura dei dati aggiornata.
Imposta il tempo di scadenza al più piccolo frame di tempo possibile quando si aggiungono dati. Anche se il tempo di scadenza predefinito è 45 giorni per entrambi MemoryStoreQueue:AddAsync() e MemoryStoreSortedMap:SetAsync(), impostando il tempo di scadenza più breve, è possibile pulire automaticamente i dati vecchi per impedire loro di riempire la tua quota di memoria
- Non memorizzare una grande quantità di dati con un'espirazione lunga, poiché rischia di superare la tua quota di memoria e potenzialmente causare problemi che possono interrompere tutta la tua esperienza.
- Elimina sempre gli oggetti non necessari o imposta un'esplosione dell'elemento breve.
- In generale, dovresti usare l'esplicito utilizzo della cancellazione per rilasciare la memoria e l'esaurimento degli oggetti come meccanismo di sicurezza per prevenire gli oggetti non utilizzati dal memoria per un periodo di tempo esteso.
Mantieni solo i valori necessari in memoria.
Ad esempio, per un'esperienza di casa d'asta, devi mantenere l'offerta più alta. Puoi usare MemoryStoreQueue:UpdateAsync() su una chiave per mantenere l'offerta più alta piuttosto che mantenere tutti gli offerte nella tua struttura di dati.
Usa backoff esponenziale per aiutare a mantenere i limiti della richiesta API sotto.
Ad esempio, se ricevi un DataUpdateConflict , potresti riprovare dopo due secondi, quindi quattro, otto, ecc. invece di inviare costantemente richieste a Class.MemoryStoreService per ottenere la risposta corretta.
Dividi le strutture dei dati giganti in più piccole spaccando .
È spesso più semplice 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 di utilizzo. Ad esempio, se hai una mappa sorta che utilizza i suffissi per le sue chiavi, considera la separazione di ciascun suffisso in una sua mappa sorta. Per un'esperienza popolarissima, potresti persino separare gli utenti in più mappe in base agli ultimi
Comprimi i valori memorizzati.
Ad esempio, considera l'uso dell'algoritmo LZW per ridurre la dimensione del valore memorizzato.
Osservabilità
La Dashboard dell'Osservabilità fornisce informazioni e analisi per il monitoraggio e il debug del tuo utilizzo della memoria. Con grafici in tempo reale su diversi aspetti del tuo utilizzo della memoria e richieste API, puoi tracciare il pattern di utilizzo della memoria della tua esperienza, visualizzare le quotazioni attuali assegnate e monitorare lo Statodella 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 sulla dashboard di richieste per stato e richieste per API x stato . Per ulteriori informazioni su come risolvere questi errori, vedi risolvere i problemi. Per il limite o la limitazione che una richiesta riguarda, vedi 2> limiti e quota2> .
Codice Stato | Descrizione |
---|---|
Successo | Successo. |
Limite di memoria dei dati | Supera il limite di dimensioni della memoria della struttura dei dati (100MB). |
Aggiornamento dei conflitti | Conflitto dovuto all'aggiornamento Aggiornarmento. |
Accesso negato | Non autorizzato ad accedere ai dati dell'esperienza. Questa richiesta non consuma unità di richiesta o utilizza quota. |
Errore interno | Errore interno. |
Richiesta non valida | La richiesta non ha le informazioni richieste o ha informazioni non formate. |
Strutture di datiLimit | Supera il limite di livelli di struttura dei dati (1M). |
Nessun oggetto trovato | Nessun elemento trovato in MemoryStoreQueue:ReadAsync() o MemoryStoreSortedMap:UpdateAsync() . ReadAsync() polls ogni 2 secondi e restituisce questo codice di stato fino a quando non trova gli elementi nella coda. |
Limitazioni di struttura dei dati | Supera il limite di livello di richiesta di struttura dei dati (100.000 unità richieste per minuto). |
Limitazioni delle richieste di partizione | Supera il limite di unità di richiesta di partizione. |
Limite di richieste totali | Supera il limite di unità di richiesta a livello dell'universo. |
Limite di memoria totale | Supera il quota di memoria a livello dell'universo. |
Dimensione dell'elemento troppo grande | Il valore della dimensione supera il limite (32KB). |
La seguente tabella elenca i codici lato client, che non sono attualmente disponibili sulla dashboard dell'osservabilità.
Codice Stato | Descrizione |
---|---|
Errore interno | Errore interno. |
Posto non pubblicato | Devi pubblicare questo luogo per usare MemoryStoreService. |
ClientAccess non valido | MemoryStoreService deve essere chiamato dal Server. |
Tempo di Scadenza non valido | Il campo 'Expirazione' 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. |
TransformCBックアップファルル | Impossibile invocare la funzione di richiamo della trasformazione. |
RequestThrottled | Richieste di MemoryStores recenti hanno colpito uno o più limiti. |
Aggiornamento conflitti | Numero massimo di tentativi superato. |
Risolvere i problemi
La seguente tabella elenca e descrive la soluzione raccomandata per ciascun codice di stato di risposta:
Errore | Opzioni di risoluzione dei problemi |
---|---|
DataStructureCommands / PartitionCommands |
|
Limite di richieste totali | |
Strutture di datiLimit | Applica le migliori pratiche per ridurre la dimensione della memoria. |
Limite di memoria dei dati | |
Limite di memoria totale | |
Aggiornamento dei conflitti | implementa un breve ritardo tra le richieste per evitare più richieste che aggiornano la stessa chiave allo stesso tempo. Per le mappe sortite, usa la funzione richiamata su Class.MemoryStoreService:UpdateAsync() . Per le mappe sortite, usa la funzione richiamata su Class.MemoryStoreQueue:RemoveAsync() . 1>Per le mappe sortite, usa la funzione richiamata su Class.MemoryStoreSortedMap:RemoveAsync() .1> 4>Per le mappe sortite, usa la funzione richiamata su Class.MemoryStorage4> 7>Per le mappe sortite, usa la funzione richiamata su Class.MemoryStorage:UpdateAsync() . 7> 0>Per le mappe sortite, usa la funzione rich |
Errore interno |
|
Richiesta non valida |
|
Dimensione dell'elemento troppo grande |
|
Test e debug in Studio
I dati in MemoryStoreService sono isolati tra Studio e la produzione, quindi la modifica dei dati in Studio non influisce sul comportamento di produzione. Ciò significa che le tue chiamate API da Studio non accedono ai dati di produzione, il che ti consente di testare in sicurezza i magazzini di memoria e nuove funzionalità prima di andare in produzione.
Il test di Studio ha gli stessi limiti e quotazioni della produzione. Per le quotazioni calcolate in base al numero di utenti, la quota risultante può essere molto piccola poiché sei l'unico utente per il test di Studio. Quando testi da Studio, potresti anche notare una latenza leggermente maggiore e tassi di errore più elevati 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 memoria store in tempo reale o quando testare in studio, usa Console del sviluppatore.