Memorie memorizzate

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

MemoryStoreService è un servizio di dati ad alta capacità e bassa latenza che fornisce un rapido storage di dati in memoria accessibile da tutti i server in una sessione live. Memorie memorizzate sono adatte per dati frequenti ed efimeri che cambiano rapidamente e non necessitano di essere durevoli, poiché sono più rapide da accedere e scompaiono al raggiungimento della durata massima. Per i dati che devono persistere tra le sessioni, utilizza data stores.

Strutture dati

Invece di accedere direttamente ai dati grezzi, le memorie memorizzate hanno tre strutture dati primitive condivise tra i server per un'elaborazione rapida: sorted map, queue, e hash map. Ogni struttura dati è adatta per determinati casi d'uso:

  • Abbinamento basato sulle abilità - Salva le informazioni sugli utenti, come il livello di abilità, in una queue condivisa tra i server, e utilizza i server lobby per eseguire l'abbinamento periodicamente.
  • Commercio e asta tra server - Abilita il commercio universale tra diversi server, dove gli utenti possono fare offerte su oggetti con prezzi che cambiano in tempo reale, utilizzando una sorted map di coppie chiave-valore.
  • Classifiche globali - Memorizza e aggiorna le classifiche degli utenti in una classifica condivisa all'interno di una sorted map.
  • Inventari condivisi - Salva gli oggetti e le statistiche dell'inventario in una hash map condivisa, dove gli utenti possono utilizzare gli oggetti dell'inventario contemporaneamente tra loro.
  • Cache per dati persistenti - Sincronizza e copia i tuoi dati persistenti in un data store in una hash map di memoria che può fungere da cache e migliorare le prestazioni del tuo gioco.

In generale, se hai bisogno di accedere ai dati in base a una chiave specifica, utilizza una hash map. Se hai bisogno che quei dati siano ordinati, usa una sorted map. Se hai bisogno di elaborare i tuoi dati in un ordine specifico, usa una queue.

Limiti e quote

Per mantenere la scalabilità e le prestazioni del sistema, le memorie memorizzate hanno quote di utilizzo dei dati per la dimensione della memoria, le richieste API e la dimensione della struttura dati.

Le memorie memorizzate hanno una politica di espulsione basata sul tempo di scadenza, noto anche come tempo di vita (TTL). Gli elementi vengono espulsi dopo che scadono e la quota di memoria viene liberata per nuove voci. Quando raggiungi il limite di memoria, tutte le richieste di scrittura successive falliscono fino a quando gli elementi non scadono o non vengono eliminati manualmente.

Quota di dimensione della memoria

La quota di memoria limita la quantità totale di memoria che un gioco può consumare. Non è un valore fisso; cambia nel tempo a seconda del numero di utenti nel gioco secondo la formula 64KB + 1.2KB * [numero di utenti]. La quota si applica a livello di gioco invece che a livello di server.

Quando gli utenti entrano nel gioco, la quota di memoria aggiuntiva è disponibile immediatamente. Quando gli utenti lasciano il gioco, la quota non si riduce immediatamente. C'è un periodo di tracciabilità di otto giorni prima che la quota venga rivalutata a un valore inferiore.

Dopo che il tuo gioco raggiunge la quota di dimensione della memoria, eventuali richieste API che aumentano la dimensione della memoria si rifiutano sempre. Le richieste che diminuiscono o non cambiano la dimensione della memoria hanno ancora successo.

Con il dashboard di osservabilità, puoi visualizzare la quota di dimensione della memoria del tuo gioco in tempo reale utilizzando il grafico Utilizzo della memoria.

Limiti delle richieste API

Una quota di unità richiesta si applica a tutte le chiamate API di MemoryStoreService. Questa quota è 1000 + 120 * [numero di utenti concorrenti] unità richieste al minuto.

La maggior parte delle chiamate API consuma solo un'unità richiesta, con alcune eccezioni:

  • MemoryStoreSortedMap:GetRangeAsync()

    Consuma unità in base al numero di elementi restituiti. Ad esempio, se questo metodo restituisce 10 elementi, la chiamata conta come 10 unità richieste. Se restituisce una risposta vuota, conta come un'unità richiesta.

  • MemoryStoreQueue:ReadAsync()

    Consuma unità in base al numero di elementi restituiti, proprio come MemoryStoreSortedMap:GetRangeAsync(), ma consuma un'unità aggiuntiva ogni due secondi mentre legge. Specifica il tempo massimo di lettura con il parametro waitTimeout.

  • MemoryStoreHashMap:UpdateAsync()

    Consuma un minimo di due unità.

  • MemoryStoreHashMap:ListItemsAsync()

    Consuma [numero di partizioni scansionate] + [elementi restituiti] unità.

La quota delle richieste si applica anche a livello di gioco invece che a livello di server. Questo fornisce flessibilità per allocare le richieste tra i server finché il tasso total di richieste non supera 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 unità richieste del tuo gioco in tempo reale.

Limiti di dimensione della struttura dati

Per una singola sorted map o queue, si applicano i seguenti limiti di dimensione e conteggio degli oggetti:

  • Numero massimo di elementi: 1.000.000
  • Dimensione totale massima (inclusi i chiavi per la sorted map): 100 MB

Limiti per partizione

Consulta limiti per partizione.

Migliori pratiche

Per mantenere il tuo utilizzo della memoria ottimale ed evitare di raggiungere i limiti, segui queste migliori pratiche:

  • Rimuovi gli elementi elaborati. Pulire costantemente gli oggetti letti utilizzando il metodo MemoryStoreQueue:RemoveAsync() per le queue e MemoryStoreSortedMap:RemoveAsync() per le sorted map può liberare memoria e mantenere la struttura dati aggiornata.

  • Imposta il tempo di scadenza al più piccolo intervallo di tempo possibile quando aggiungi dati. Anche se il tempo di scadenza predefinito è di 45 giorni per sia MemoryStoreQueue:AddAsync() che MemoryStoreSortedMap:SetAsync(), impostare il tempo più breve possibile può pulire automaticamente i dati vecchi per impedire che riempiano la tua quota di utilizzo della memoria.

    • Non memorizzare una grande quantità di dati con una scadenza lunga, poiché c'è il rischio di superare la tua quota di memoria e potenzialmente causare problemi che possono rompere tutto il tuo gioco.
    • Eliminare sempre esplicitamente oggetti non necessari o impostare una breve scadenza per gli oggetti.
    • In generale, dovresti utilizzare l'eliminazione esplicita per liberare memoria e la scadenza degli oggetti come meccanismo di sicurezza per impedire agli oggetti non utilizzati di occupare memoria per un lungo periodo di tempo.
  • Mantieni in memoria solo i valori necessari.

    Ad esempio, per un gioco di asta, devi solo mantenere la migliore offerta. Puoi utilizzare MemoryStoreSortedMap:UpdateAsync() su una chiave per mantenere la migliore offerta piuttosto che mantenere tutte le offerte nella tua struttura dati.

  • Usa backoff esponenziale per aiutare a stare sotto i limiti delle richieste API.

    Ad esempio, se ricevi un DataUpdateConflict, potresti riprovare dopo due secondi, quindi quattro, otto, ecc. piuttosto che inviare continuamente richieste a MemoryStoreService per ottenere la risposta corretta.

  • Dividi le enormi strutture dati in più più piccole tramite sharding.

    È spesso più facile gestire i dati in strutture più piccole piuttosto che memorizzare tutto in un'unica grande struttura dati. Questo approccio può aiutare anche a evitare limiti di utilizzo e tassi. Ad esempio, se hai una sorted map che usa prefissi per le sue chiavi, considera di separare ogni prefisso in una propria sorted map. Per un gioco particolarmente popolare, potresti persino separare gli utenti in più mappe in base alle ultime cifre dei loro ID utente.

  • Shard le chiavi frequentemente accedute nelle hash map con copie multiple della chiave per distribuire il carico.

  • Comprimi i valori memorizzati.

    Ad esempio, considera di utilizzare l'algoritmo LZW per ridurre la dimensione del valore memorizzato.

  • Iscriviti ai Servizi Estesi.

    Puoi aumentare le tue quote di Storage e Request Limit iscrivendoti ai Servizi Estesi.

Osservabilità

Il Dashboard di Osservabilità fornisce approfondimenti e analisi per monitorare e risolvere i problemi del tuo utilizzo della memoria memorizzata. Con grafici aggiornati in tempo reale su diversi aspetti del tuo utilizzo della memoria e delle richieste API, puoi tracciare il modello di utilizzo della memoria del tuo gioco, visualizzare le quote attualmente allocate, monitorare lo stato delle 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 nei grafici Conteggio delle richieste per stato e Richieste per API x Stato del Dashboard di Osservabilità. Per ulteriori informazioni su come risolvere questi errori, consulta Risoluzione dei problemi. Per la quota o il limite specifico a cui si riferisce un errore, consulta Limiti e Quote.

Codice di statoDescrizione
SuccessoSuccesso.
DataStructureMemoryOverLimitSupera il limite di dimensione della memoria a livello di struttura dati (100MB).
DataUpdateConflictConflitto a causa di un aggiornamento concorrente.
AccessDeniedNon autorizzato ad accedere ai dati di gioco. Questa richiesta non consuma unità richieste né utilizza la quota.
InternalErrorErrore interno.
InvalidRequestLa richiesta non contiene le informazioni richieste o ha informazioni malformate.
DataStructureItemsOverLimitSupera il limite di conteggio degli elementi a livello di struttura dati (1M).
NoItemFoundNessun elemento trovato in MemoryStoreQueue:ReadAsync() o MemoryStoreSortedMap:UpdateAsync(). ReadAsync() interroga ogni 2 secondi e restituisce questo codice di stato fino a quando non trova elementi nella coda.
DataStructureRequestsOverLimitSupera il limite di unità di richiesta a livello di struttura dati (100.000 unità richieste al minuto).
PartitionRequestsOverLimitSupera il limite di unità di richiesta per partizione.
TotalRequestsOverLimitSupera il limite di unità di richiesta a livello di universo.
TotalMemoryOverLimitSupera la quota di memoria a livello di universo.
ItemValueSizeTooLargeLa dimensione del valore supera il limite (32KB).

La seguente tabella elenca i codici di stato dal lato client, che attualmente non sono disponibili nel Dashboard di Osservabilità.

Codice di statoDescrizione
InternalErrorErrore interno.
UnpublishedPlaceDevi pubblicare questo luogo per utilizzare MemoryStoreService.
InvalidClientAccessMemoryStoreService deve essere chiamato dal server.
InvalidExpirationTimeIl campo 'expiration' deve essere compreso tra 0 e 3,888,000.
InvalidRequestImpossibile convertire il valore in json.
InvalidRequestImpossibile convertire sortKey in un numero o stringa valida.
TransformCallbackFailedImpossibile invocare la funzione di callback di trasformazione.
RequestThrottledRichieste recenti a MemoryStores hanno raggiunto uno o più limiti.
UpdateConflictSuperato il numero massimo di tentativi.

Risoluzione dei problemi

La seguente tabella elenca e descrive le soluzioni raccomandate 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 ricontrollando dopo un certo intervallo di tempo, come 30 secondi.
  • Usa il grafico Conteggio richieste per stato per verificare che tu stia ricevendo più risposte Successo rispetto a Nessun elemento trovato. Limita il numero di volte in cui colpisci MemoryStoreService con una richiesta fallita.
  • Implementa un breve ritardo tra le richieste.
  • Segui le migliori pratiche, inclusi:
    • Sharding delle tue strutture dati se ricevi un numero significativo di risposte DataStructureRequestsOverLimit/PartitionRequestsOverLimit.
    • Sharding delle chiavi della tua hash map se ricevi un numero significativo di risposte PartitionRequestsOverLimit sulle chiamate della hash map.
    • Ridurre o raggruppare le chiamate a specifiche strutture dati o chiavi hash map se vedi risposta PartitionRequestsOverLimit.
    • Implementa un backoff esponenziale per trovare una ragionevole frequenza di richieste da inviare.
TotalRequestsOverLimit
DataStructureItemsOverLimit
DataStructureMemoryOverLimit
TotalMemoryOverLimit
DataUpdateConflict
  • Implementa un breve ritardo tra le richieste per evitare che più richieste aggiornino la stessa chiave contemporaneamente.
  • Per le sorted map, usa la funzione di callback nel metodo MemoryStoreSortedMap:UpdateAsync() per abortire una richiesta dopo un certo numero di tentativi, come nel seguente esempio di codice:
  • Esempio di abortire richiesta

    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("l'elemento è "..item.highestBid)
    return nil
    end, 1000)
    end
    placeBid("MyItem", 50)
    placeBid("MyItem", 40)
    print("fatto")
  • Investiga per vedere se stai chiamando MemoryStoreService in modo efficiente per evitare conflitti. Idealmente, non dovresti sovraccaricare con richieste.
  • Rimuovi costantemente gli elementi una volta letti utilizzando il metodo MemoryStoreQueue:RemoveAsync() per le queue e MemoryStoreSortedMap:RemoveAsync() per le sorted map.
Errore interno
Richiesta non valida
  • Assicurati di includere parametri corretti e validi nella tua richiesta. Esempi di parametri non validi includono:
    • Una stringa vuota
    • Una stringa che supera il limite di lunghezza
Dimensione del valore dell'elemento troppo grande
  • Shard o dividi il valore dell'elemento in più chiavi.
    • Per organizzare le chiavi raggruppate, ordinale alfabeticamente aggiungendo un prefix alla chiave.
  • Codifica o comprimere i valori memorizzati.

Test e debug in Studio

I dati in MemoryStoreService sono isolati tra Studio e produzione, quindi cambiare i dati in Studio non influisce sul comportamento della produzione. Ciò significa che le tue chiamate API da Studio non accedono ai dati di produzione, consentendoti di testare in sicurezza le memorie memorizzate e nuove funzionalità prima di andare in produzione.

Il testing in 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 il testing in Studio. Quando testate da Studio, potresti anche notare una latenza leggermente più alta e tassi di errore elevati rispetto all'uso in produzione a causa di ulteriori controlli che vengono eseguiti per verificare l'accesso e le autorizzazioni.

Per informazioni su come debug un memoria memorizzata nei giochi live o quando testi in studio, utilizza la Console Sviluppatore.

© 2026 Roblox Corporation. Roblox, il logo Roblox e Powering Imagination sono tra i nostri marchi registrati e non registrati negli Stati Uniti. e altri paesi.