Magazzini di memoria

*Questo contenuto è tradotto usando AI (Beta) e potrebbe contenere errori. Per visualizzare questa pagina in inglese, clicca qui.

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.

  • MemoryStoreQueue:ReadAsync()

    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 codiceDescrizione
SuccessoSuccesso.
Memoria di struttura dati oltre il limiteSupera il limite della dimensione della memoria della struttura dei dati (100MB).
Conflicto di aggiornamento dei datiConflitto dovuto all'aggiornamento Aggiornarmento.
Accesso negatoNon autorizzato ad accedere ai dati dell'esperienza. Questa richiesta non consuma unità di richiesta o utilizza la quota.
Errore internoErrore interno.
Richiesta non validaLa richiesta non ha le informazioni richieste o ha informazioni malformate.
Struttura datiItemOverLimitSupera il limite del numero di elementi della struttura dei dati (1M).
Nessun oggetto trovatoNessun 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 limiteSupera il limite di richiesta di livello della struttura dei dati (100.000 richieste all'ora).
Partizione richieste overlimitSupera il limite di richiesta di partizione.
Richieste totali overlimitSupera il limite di unità di richiesta a livello dell'universo.
Memoria totale oltre limiteSupera la quota di memoria a livello dell'universo.
ItemValueSizeTooLarge troppo grandeLa 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 codiceDescrizione
Errore internoErrore interno.
Posto non pubblicatoDevi pubblicare questo luogo per utilizzare MemoryStoreService.
Accesso client non validoMemoryStoreService deve essere chiamato dal Server.
Tempo di scadenza invalidoIl campo 'scadenza' deve essere tra 0 e 3,888,000.
Richiesta non validaImpossibile convertire il valore in json.
Richiesta non validaImpossibile convertire sortKey in un numero o una Stringavalida.
TrasformCallbackFailedImpossibile invocare la funzione di richiamo della trasformazione.
RichiestaThrottledLe richieste recenti di MemoryStores hanno superato uno o più limiti.
Aggiorna conflittoSuperato il numero massimo di riprobi.

Risoluzione dei problemi

La seguente tabella elenca e descrive la soluzione raccomandata per ciascun codice di stato di risposta:

ErroreOpzioni di risoluzione dei problemi
DataStructureRequestsOverLimit / PartitionRequestsOverLimit
  • Aggiungi una cache locale salvando le informazioni in un'altra variabile e controllando nuovamente dopo un determinato intervallo di tempo, come 30 secondi.:
  • Usa la tabella Request Count by Status per verificare che stai ricevendo più risposte di successo rispetto a NoItemFounds .Limita il numero di volte in cui raggiungi MemoryStoreService con una Richiestafallita.:
  • Implementa un breve ritardo tra le richieste.:
  • Segui le migliori pratiche , tra cui:
    • Frammentare le tue strutture di dati se ricevi una quantità significativa di Richieste di strutture di datiOltreLimite / Richieste di partizioneOltreLimite risposte.:
    • Implementa un ritiro esponenziale per trovare un tasso ragionevole di richieste da Spedire.
Richieste totali overlimit
Struttura datiItemOverLimit
Memoria di struttura dati oltre il limite
Memoria totale oltre limite
Conflicto di aggiornamento dei dati
  • Implementa un breve ritardo tra le richieste per evitare che più richieste aggiornino la stessa chiave allo stesso tempo.:
  • Per le mappe ordinate, utilizza la funzione di richiamo sul metodo MemoryStoreSortedMap:UpdateAsync() per annullare una richiesta dopo un certo numero di tentativi, come mostra il seguente esempio di codice:
  • Example of Aborting Request

    local MemoryStoreService = game:GetService("MemoryStoreService")
    local map = MemoryStoreService:GetSortedMap("AuctionItems")
    function placeBid(itemKey, bidAmount)
    map:UpdateAsync(itemKey, function(item)
    item = item or { highestBid = 0 }
    if item.highestBid < bidAmount then
    item.highestBid = bidAmount
    return item
    end
    print("item is "..item.highestBid)
    return nil
    end, 1000)
    end
    placeBid("MyItem", 50)
    placeBid("MyItem", 40)
    print("done")
  • 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
  • Assicurati di includere parametri corretti e validi nella tua Richiesta. Gli esempi di parametri non validi includono:
    • Una stringa vuota
    • Una stringa che supera il limite di lunghezza
    • >

ItemValueSizeTooLarge troppo grande
  • Frammenta o dividi il valore dell'oggetto in più chiavi.
    • Per organizzare le chiavi in gruppo, ordinali alfabeticamente aggiungendo una prefix alla chiave.
    • >

  • Codifica o compressione dei valori memorizzati.

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.