Memorie

*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 attiva. Memory Stores sono adatti per dati frequenti ed effimeri che cambiano rapidamente e non necessitano di essere durevoli, poiché sono più veloci da accedere e scompaiono quando raggiungono la durata massima. Per i dati che devono persistere tra le sessioni, utilizzare data stores.

Strutture dati

Invece di accedere direttamente ai dati grezzi, i memory stores hanno tre strutture dati primitive condivise tra i server per un'elaborazione rapida: mappa ordinata, coda e mappa hash. Ogni struttura dati è adatta per determinati casi d'uso:

  • Abbinamento basato sulle abilità - Salva le informazioni degli utenti, come il livello di abilità, in una coda condivisa tra i server e utilizza i server di 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 mappa ordinata di coppie chiave-valore.
  • Classifiche globali - Memorizza e aggiorna le classifiche degli utenti su una classifica condivisa all'interno di una mappa ordinata.
  • Inventari condivisi - Salva gli oggetti dell'inventario e le statistiche in una mappa hash 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 mappa hash 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 mappa hash. Se hai bisogno che i dati siano ordinati, utilizza una mappa ordinata. Se hai bisogno di elaborare i tuoi dati in un ordine specifico, utilizza una coda.

Limiti e quote

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

I memory stores hanno una politica di espulsione basata sul tempo di scadenza, noto anche come tempo di vita (TTL). Gli oggetti vengono espulsi dopo la scadenza 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 oggetti non scadono o non li elimini 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; invece, cambia nel tempo a seconda del numero di utenti nel gioco secondo la formula 64 KB + 1,2 KB * [numero di utenti]. La quota si applica a livello di gioco anziché a livello di server.

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

Dopo che il tuo gioco ha raggiunto la quota di dimensione della memoria, qualsiasi richiesta API che aumenta la dimensione della memoria fallisce sempre. Le richieste che diminuiscono o non cambiano la dimensione della memoria continuano a riuscire.

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à di richiesta si applica a tutte le chiamate API di MemoryStoreService. Questa quota è 1000 + 120 * [numero di utenti concorrenti] unità di richiesta al 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 elementi restituiti. Ad esempio, se questo metodo restituisce 10 elementi, la chiamata conta come 10 unità di richiesta. Se restituisce una risposta vuota, conta come un'unità di richiesta.

  • MemoryStoreQueue:ReadAsync()

    Consuma unità in base al numero di elementi restituiti, proprio come MemoryStoreSortedMap:GetRangeAsync(), ma consuma un'unità aggiuntiva ogni due secondi durante la lettura. 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 anziché a livello di server. Questo fornisce flessibilità per allocare le richieste tra i server finché il tasso totale 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 di osservabilità disponibile, puoi visualizzare la quota di unità di richiesta del tuo gioco in tempo reale.

Limiti di dimensione della struttura dati

Per una singola mappa ordinata o coda, si applicano i seguenti limiti di dimensione e conteggio degli elementi:

  • Numero massimo di elementi: 1.000.000
  • Dimensione totale massima (inclusi i tasti per la mappa ordinata): 100 MB

Limiti per partizione

Vedi limiti per partizione.

Migliori pratiche

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

  • Rimuovi gli elementi elaborati. Pulire costantemente 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 dati aggiornata.

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

    • Non memorizzare una grande quantità di dati con una lunga scadenza, poiché rischia di superare la tua quota di memoria e potenzialmente causare problemi che possono rompere l'intero gioco.
    • Elimina sempre esplicitamente gli elementi non necessari o imposta una breve scadenza per gli elementi.
    • In generale, dovresti utilizzare la cancellazione esplicita per liberare memoria e la scadenza degli elementi come meccanismo di sicurezza per prevenire che gli elementi non utilizzati occupino memoria per un lungo periodo di tempo.
  • Mantieni solo i valori necessari in memoria.

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

  • Usa backoff esponenziale per aiutarti a rimanere al di sotto dei limiti delle richieste API.

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

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

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

  • Shard chiavi frequentemente accessibili nelle mappe hash con più copie 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 Limiti di Memoria e Richiesta iscrivendoti ai Servizi Estesi.

Osservabilità

Il Dashboard di Osservabilità fornisce informazioni e analisi per monitorare e risolvere i problemi relativi all'utilizzo del tuo memory store. Con grafici che si aggiornano 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 richieste per stato e Richieste per API x Stato del Dashboard di Osservabilità. Per ulteriori informazioni su come risolvere questi errori, vedere Risoluzione dei problemi. Per la quota o il limite specifico a cui si riferisce un errore, vedere Limiti e Quote.

Codice di statoDescrizione
SuccessoSuccesso.
DataStructureMemoryOverLimitSupera il limite di dimensione della memoria a livello di struttura dati (100 MB).
DataUpdateConflictConflitto a causa di un aggiornamento concorrente.
AccessDeniedNon autorizzato ad accedere ai dati di gioco. Questa richiesta non consuma unità di richiesta né utilizza la quota.
InternalErrorErrore interno.
InvalidRequestLa richiesta non ha 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à di richiesta 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 (32 KB).

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.
RequestThrottledLe recenti richieste a MemoryStores hanno colpito uno o più limiti.
UpdateConflictSuperato il numero massimo di tentativi.

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 ricontrollando dopo un certo intervallo di tempo, come 30 secondi.
  • Utilizza il grafico Conteggio richieste per stato per verificare che stai 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:
    • Shardare le tue strutture dati se ricevi un numero significativo di risposte DataStructureRequestsOverLimit/PartitionRequestsOverLimit.
    • Shardare le chiavi della tua mappa hash se ricevi un numero significativo di risposte PartitionRequestsOverLimit sulle chiamate della mappa hash.
    • Ridurre o raggruppare le chiamate a specifiche strutture dati o chiavi della mappa hash se vedi risposte PartitionRequestsOverLimit.
    • Implementa un backoff esponenziale per trovare un tasso ragionevole 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 mappe ordinate, utilizza la funzione di callback sul metodo MemoryStoreSortedMap:UpdateAsync() per abortire una richiesta dopo un certo numero di tentativi, come mostra il seguente esempio di codice:
  • Esempio di Aborto 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")
  • Indaga per vedere se stai chiamando MemoryStoreService in modo efficiente per evitare conflitti. Idealmente, non dovresti inviare richieste eccessive.
  • Rimuovi costantemente gli elementi una volta letti utilizzando il metodo MemoryStoreQueue:RemoveAsync() per le code e MemoryStoreSortedMap:RemoveAsync() per le mappe ordinate.
Errore interno
InvalidRequest
  • 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
ItemValueSizeTooLarge
  • Shardare o dividere il valore dell'elemento in più chiavi.
    • Per organizzare le chiavi raggruppate, ordinale alfabeticamente aggiungendo un prefisso alla chiave.
  • Codificare o comprimere i valori memorizzati.

Test e debug in Studio

I dati in MemoryStoreService sono isolati tra Studio e produzione, quindi modificare i dati in Studio non influisce sul comportamento della produzione. Questo significa che le tue chiamate API da Studio non accedono ai dati di produzione, consentendoti di testare in sicurezza i memory stores e le nuove funzionalità prima di passare alla 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 testi da Studio, potresti anche notare una latenza leggermente più alta e tassi di errore elevati rispetto all'uso in produzione a causa di alcuni controlli aggiuntivi che vengono eseguiti per verificare accesso e permessi.

Per informazioni su come eseguire il debug di un memory store nei giochi dal vivo o quando si testa in studio, utilizza la Console per sviluppatori.

© 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.