Speicher für Daten

*Dieser Inhalt wurde mit KI (Beta) übersetzt und kann Fehler enthalten. Um diese Seite auf Englisch zu sehen, klicke hier.

MemoryStoreService ist ein Hochdurchsatz- und Niedriglatenz-Dienst, der schnellen Zugriff auf Speicherplatz für Daten in Echtzeit von allen Servern in einer aktiven Sitzung ermöglicht. Speicher für Daten eignet sich für häufige und flüchtige Daten, die sich schnell ändern und nicht dauerhaft sein müssen, da sie schneller zugänglich sind und verschwinden, wenn die maximale Lebensdauer erreicht ist. Verwenden Sie für Daten, die über Sitzungen hinweg bestehen bleiben müssen, Datenläden.

Datenstrukturen

Anstatt direkt auf Rohdaten zuzugreifen, verfügen Speicher für Daten über drei primitive Datenstrukturen, die serverübergreifend für eine schnelle Verarbeitung gemeinsam genutzt werden: sortierte Map, Warteschlange und Hash-Map. Jede Datenstruktur eignet sich gut für bestimmte Anwendungsfälle:

  • Fähigkeitsbasiertes Matchmaking - Speichern Sie Benutzerinformationen, wie zum Beispiel die Fähigkeitsstufe, in einer gemeinsamen Warteschlange zwischen den Servern und verwenden Sie Lobbys, um regelmäßig Matchmaking durchzuführen.
  • Serverübergreifender Handel und Auktionen - Ermöglichen Sie den universellen Handel zwischen verschiedenen Servern, bei dem Benutzer auf Gegenstände mit sich in Echtzeit ändernden Preisen bieten können, mit einer sortierten Map von Schlüssel-Wert-Paaren.
  • Globale Bestenlisten - Speichern und aktualisieren Sie Benutzer-Rankings auf einer gemeinsamen Bestenliste innerhalb einer sortierten Map.
  • Geteilte Inventare - Speichern Sie Inventarartikel und Statistiken in einer gemeinsamen Hash-Map, wo Benutzer Inventarartikel gleichzeitig nutzen können.
  • Cache für persistente Daten - Synchronisieren und kopieren Sie Ihre persistenten Daten in einem Datenlager zu einer Speicher-Hash-Map, die als Cache fungieren kann und die Leistung Ihres Spiels verbessert.

Im Allgemeinen, wenn Sie auf Daten basierend auf einem bestimmten Schlüssel zugreifen müssen, verwenden Sie eine Hash-Map. Wenn diese Daten sortiert sein müssen, verwenden Sie eine sortierte Map. Wenn Sie Ihre Daten in einer bestimmten Reihenfolge verarbeiten müssen, verwenden Sie eine Warteschlange.

Grenzen und Quoten

Um die Skalierbarkeit und Systemleistung aufrechtzuerhalten, haben Speicher für Daten Datenverwendungsquoten für die Speichermenge, API-Anfragen und die Größe der Datenstruktur.

Speicher für Daten haben eine Räumungsrichtlinie, die auf der Ablaufzeit basiert, auch bekannt als Lebensdauer (TTL). Elemente werden nach ihrer Ablaufzeit geräumt, und das Speicherplatzkontingent wird für neue Einträge freigegeben. Wenn Sie das Speicherlimit erreichen, schlagen alle nachfolgenden Schreibanfragen fehl, bis Elemente ablaufen oder Sie diese manuell löschen.

Quotierung der Speichermenge

Das Speicherplatzkontingent begrenzt die gesamte Menge an Speicher, die ein Spiel verbrauchen kann. Es ist kein fester Wert; vielmehr ändert es sich im Laufe der Zeit je nach der Anzahl der Benutzer im Spiel gemäß der Formel 64KB + 1.2KB * [Anzahl der Benutzer]. Das Kontingent gilt auf Spielebene anstelle von Serverebene.

Wenn Benutzer dem Spiel beitreten, ist das zusätzliche Speicherplatzkontingent sofort verfügbar. Wenn Benutzer das Spiel verlassen, verringert sich das Kontingent nicht sofort. Es gibt eine Rückverfolgungszeit von acht Tagen, bis das Kontingent erneut auf einen niedrigeren Wert bewertet wird.

Nachdem Ihr Spiel das Quota für die Speichermenge erreicht hat, schlagen alle API-Anfragen, die die Speichermenge erhöhen, fehl. Anfragen, die die Speichermenge verringern oder nicht ändern, sind weiterhin erfolgreich.

Mit dem Überwachungs Dashboard können Sie das Speicherplatzkontingent Ihres Spiels in Echtzeit mithilfe des Speichernutzungs-Diagramms einsehen.

API-Anfragegrenzen

Eine Anfrageeinheit-Quote gilt für alle MemoryStoreService API-Aufrufe. Diese Quote beträgt 1000 + 120 * [Anzahl der gleichzeitigen Benutzer] Anfrageeinheiten pro Minute.

Die meisten API-Aufrufe verbrauchen nur eine Anfrageeinheit, mit einigen Ausnahmen:

  • MemoryStoreSortedMap:GetRangeAsync()

    Verbraucht Einheiten basierend auf der Anzahl der zurückgegebenen Elemente. Wenn diese Methode beispielsweise 10 Elemente zurückgibt, zählt der Aufruf als 10 Anfrageeinheiten. Wenn sie eine leere Antwort zurückgibt, zählt es als eine Anfrageeinheit.

  • MemoryStoreQueue:ReadAsync()

    Verbraucht Einheiten basierend auf der Anzahl der zurückgegebenen Elemente, genau wie MemoryStoreSortedMap:GetRangeAsync(), verbraucht jedoch eine zusätzliche Einheit alle zwei Sekunden während des Lesens. Geben Sie die maximalen Lesezeit mit dem Parameter waitTimeout an.

  • MemoryStoreHashMap:UpdateAsync()

    Verbraucht mindestens zwei Einheiten.

  • MemoryStoreHashMap:ListItemsAsync()

    Verbraucht [Anzahl der gescannten Partitionen] + [zurückgegebene Elemente] Einheiten.

Das Anfragenkontingent wird ebenfalls auf Spielebene anstelle von Serverebene angewendet. Dies bietet Flexibilität bei der Zuweisung der Anfragen unter Servern, solange die Gesamtraten von Anfragen das Kontingent nicht überschreiten. Wenn Sie das Kontingent überschreiten, erhalten Sie eine Fehlermeldung, wenn der Dienst Ihre Anfragen drosselt.

Mit der verfügbaren Überwachungs -Funktion können Sie die Anbieterquoten Ihres Spiels in Echtzeit anzeigen.

Grenzen der Datenstrukturgröße

Für eine einzelne sortierte Map oder Warteschlange gelten die folgenden Größen- und Elementanzahlgrenzen:

  • Maximale Anzahl von Elementen: 1.000.000
  • Maximale Gesamtgröße (einschließlich Schlüssel für sortierte Maps): 100 MB

Grenzen pro Partition

Siehe Grenzen pro Partition.

Beste Praktiken

Um Ihr Speicherverbrauchsmuster optimal zu halten und zu vermeiden, dass Sie die Grenzen erreichen, befolgen Sie diese besten Praktiken:

  • Entfernen Sie verarbeitete Elemente. Durch konsequente Bereinigung gelesener Elemente mithilfe der Methode MemoryStoreQueue:RemoveAsync() für Warteschlangen und MemoryStoreSortedMap:RemoveAsync() für sortierte Maps können Sie Speicher freigeben und die Datenstruktur aktuell halten.

  • Setzen Sie die Ablaufzeit auf den kleinsten möglichen Zeitraum, wenn Sie Daten hinzufügen. Obwohl die Standard-Ablaufzeit sowohl für MemoryStoreQueue:AddAsync() als auch für MemoryStoreSortedMap:SetAsync() 45 Tage beträgt, kann das Festlegen der kürzest möglichen Zeit dazu beitragen, alte Daten automatisch zu bereinigen, um zu verhindern, dass sie Ihr Speicherplatzkontingent füllen.

    • Speichern Sie keine große Menge an Daten mit einer langen Ablaufzeit, da dies das Risiko birgt, Ihr Speicherplatzkontingent zu überschreiten und potenziell Probleme zu verursachen, die Ihr gesamtes Spiel beeinträchtigen könnten.
    • Löschen Sie immer entweder explizit nicht benötigte Elemente oder setzen Sie eine kurze Ablaufzeit für die Elemente.
    • Allgemein sollten Sie für das Freigeben von Speicher explizites Löschen verwenden und die Ablaufzeit von Elementen als Sicherheitsmechanismus, um zu verhindern, dass unbenutzte Elemente Speicher über einen längeren Zeitraum belegen.
  • Halten Sie nur notwendige Werte im Speicher.

    Zum Beispiel, für ein Auktionshaus-Spiel müssen Sie nur das höchste Gebot beibehalten. Sie können MemoryStoreSortedMap:UpdateAsync() für einen Schlüssel verwenden, um das höchste Gebot aufrechtzuerhalten, anstatt alle Gebote in Ihrer Datenstruktur zu verwalten.

  • Verwenden Sie exponentielles zurückgestufte, um unter den API-Anfragegrenzen zu bleiben.

    Wenn Sie beispielsweise einen DataUpdateConflict erhalten, sollten Sie nach zwei Sekunden erneut versuchen, dann vier, acht usw., anstatt ständig Anfragen an MemoryStoreService zu senden, um die korrekte Antwort zu erhalten.

  • Teilen Sie große Datenstrukturen in mehrere kleinere auf, indem Sie Sharding verwenden.

    Es ist oft einfacher, Daten in kleineren Strukturen zu verwalten, anstatt alles in einer großen Datenstruktur zu speichern. Dieser Ansatz kann auch helfen, Verbrauchs- und Ratenlimits zu vermeiden. Wenn Sie beispielsweise eine sortierte Map haben, die Präfixe für ihre Schlüssel verwendet, sollten Sie in Erwägung ziehen, jede Präfix in seine eigene sortierte Map zu trennen. Für ein besonders beliebtes Spiel könnten Sie sogar Benutzer in mehrere Karten basierend auf den letzten Ziffern ihrer Benutzer-IDs trennen.

  • Shard häufig aufgerufene Schlüssel in Hash-Maps mit mehreren Kopien des Schlüssels, um die Last zu verteilen.

  • Komprimieren Sie gespeicherte Werte.

    Ziehen Sie in Betracht, den LZW Algorithmus zu verwenden, um die Größe des gespeicherten Wertes zu reduzieren.

  • Melden Sie sich für erweiterte Services an.

    Sie können Ihre Speicher- und Anfragegrenzen erhöhen, indem Sie sich für erweiterte Services anmelden.

Überwachbarkeit

Das Überwachungs-Dashboard bietet Einblicke und Analysen zur Überwachung und Fehlersuche Ihrer Nutzung von Speicher für Daten. Mit in Echtzeit aktualisierten Diagrammen zu verschiedenen Aspekten Ihres Speicherverbrauchs und Ihrer API-Anfragen können Sie das Muster der Speichernutzung Ihres Spiels verfolgen, die aktuell zugewiesenen Quoten einsehen, den API-Status überwachen und potenzielle Probleme zur Leistungsoptimierung identifizieren.

Die folgende Tabelle listet alle Statuscodes der API-Antworten auf, die auf den Diagrammen Anzahl der Anfragen nach Status und Anfragen nach API x Status des Überwachungsdashboards verfügbar sind. Weitere Informationen zur Behebung dieser Fehler finden Sie unter Fehlerbehebung. Für das spezifische Quoten- oder Limit, das eine Fehlermeldung betrifft, siehe Grenzen und Quoten.

StatuscodeBeschreibung
ErfolgErfolg.
DataStructureMemoryOverLimitÜberschreitet das Datenstrukturniveau für die Speichermenge (100MB).
DataUpdateConflictKonflikt aufgrund gleichzeitiger Aktualisierung.
ZugriffVerweigertUnbefugter Zugriff auf Spieldaten. Diese Anfrage verbraucht keine Anfrageeinheiten oder nutzt das Kontingent nicht.
InternerFehlerInterner Fehler.
UngültigeAnfrageDie Anfrage enthält nicht die erforderlichen Informationen oder hat fehlerhafte Informationen.
DataStructureItemsOverLimitÜberschreitet die Anzahl der Elemente im Datenstrukturlevel (1M).
KeinElementGefundenKein Element in MemoryStoreQueue:ReadAsync() oder MemoryStoreSortedMap:UpdateAsync() gefunden. ReadAsync() pollt alle 2 Sekunden und gibt diesen Statuscode zurück, bis es Elemente in der Warteschlange findet.
DataStructureRequestsOverLimitÜberschreitet die Anfrageeinheitgrenze auf Datenstrukturebene (100.000 Anfrageeinheiten pro Minute).
PartitionRequestsOverLimitÜberschreitet die Partition-Anfrageeinheitgrenze.
GesamtAnfragenÜberLimitÜberschreitet die Anfrageeinheitgrenze auf Universumsebene.
GesamtSpeicherÜberLimitÜberschreitet das Speicherquotenlimit auf Universumsebene.
ElementWertGrößeZuGroßWertgröße überschreitet das Limit (32KB).

Die folgende Tabelle listet Statuscodes von der Clientseite auf, die derzeit nicht im Überwachungs-Dashboard verfügbar sind.

StatuscodeBeschreibung
InternerFehlerInterner Fehler.
UnveröffentlichtenPlatzSie müssen diesen Platz veröffentlichen, um MemoryStoreService verwenden zu können.
UngültigerClientZugriffMemoryStoreService muss vom Server aus aufgerufen werden.
UngültigeAblaufzeitDas Feld 'Ablaufzeit' muss zwischen 0 und 3.888.000 liegen.
UngültigeAnfrageWert kann nicht in json konvertiert werden.
UngültigeAnfrageSortKey kann nicht in eine gültige Zahl oder Zeichenfolge konvertiert werden.
TransformCallbackFehlgeschlagenDie Transformation Callback-Funktion konnte nicht aufgerufen werden.
AnfrageDrosselungNeueste Anfragen an Speicher für Daten haben eines oder mehrere Limits erreicht.
AktualisierungsKonfliktMaximale Anzahl an Wiederholungen überschritten.

Fehlerbehebung

Die folgende Tabelle listet die empfohlenen Lösungen für jeden Antwortstatuscode auf:

FehlerFehlerbehebungsoptionen
DataStructureRequestsOverLimit / PartitionRequestsOverLimit
  • Fügen Sie einen lokalen Cache hinzu, indem Sie Informationen in einer anderen Variablen speichern und nach einem bestimmten Zeitintervall, wie 30 Sekunden, erneut überprüfen.
  • Verwenden Sie das Diagramm Anfragenanzahl nach Status, um zu überprüfen, ob Sie mehr Erfolg-Antworten als KeinElementGefunden-Antworten erhalten. Beschränken Sie die Anzahl der Male, die Sie MemoryStoreService mit einer fehlgeschlagenen Anfrage erreichen.
  • Implementieren Sie eine kurze Verzögerung zwischen den Anfragen.
  • Folgen Sie den besten Praktiken, einschließlich:
    • Sharding Ihrer Datenstrukturen, wenn Sie eine signifikante Anzahl von DataStructureRequestsOverLimit/PartitionRequestsOverLimit-Antworten erhalten.
    • Sharding Ihrer Hash-Map-Schlüssel, wenn Sie eine signifikante Anzahl von PartitionRequestsOverLimit-Antworten bei Hash-Map-Aufrufen erhalten.
    • Reduzieren oder Bündeln von Anfragen an bestimmte Datenstrukturen oder Hash-Map-Schlüssel, wenn Sie PartitionRequestsOverLimit-Antworten sehen.
    • Implementieren Sie einen exponentiellen Rückgang, um eine vernünftige Anfrageanzahl zu senden.
GesamtAnfragenÜberLimit
DataStructureItemsOverLimit
DataStructureMemoryOverLimit
GesamtSpeicherÜberLimit
DataUpdateConflict
  • Implementieren Sie eine kurze Verzögerung zwischen den Anfragen, um zu vermeiden, dass mehrere Anfragen gleichzeitig denselben Schlüssel aktualisieren.
  • Verwenden Sie bei sortierten Maps die Rückruffunktion in der MemoryStoreSortedMap:UpdateAsync()-Methode, um eine Anfrage nach einer bestimmten Anzahl von Versuchen abzubrechen, wie im folgenden Codesegment gezeigt:
  • Beispiel für das Abbrechen einer Anfrage

    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")
  • Untersuchen Sie, ob Sie MemoryStoreService effizient aufrufen, um Konflikte zu vermeiden. Idealerweise sollten Sie nicht übermäßig Anfragen senden.
  • Entfernen Sie konsequent Elemente, sobald sie gelesen wurden, mithilfe der Methode MemoryStoreQueue:RemoveAsync() für Warteschlangen und MemoryStoreSortedMap:RemoveAsync() für sortierte Maps.
Interner Fehler
Ungültige Anfrage
  • Stellen Sie sicher, dass Sie korrekte und gültige Parameter in Ihrer Anfrage einschließen. Beispiele für ungültige Parameter sind:
    • Ein leerer String
    • Ein String, der das Längenlimit überschreitet
ElementWertGrößeZuGroß
  • Shard oder teilen Sie den Elementwert in mehrere Schlüssel auf.
    • Um gruppierte Schlüssel zu organisieren, sortieren Sie sie alphabetisch, indem Sie ein präfix zum Schlüssel hinzufügen.
  • Codieren oder komprimieren Sie gespeicherte Werte.

Testen und Debuggen im Studio

Die Daten in MemoryStoreService sind zwischen Studio und Produktion isoliert, sodass Änderungen an den Daten im Studio das Produktionsverhalten nicht beeinflussen. Das bedeutet, dass Ihre API-Aufrufe aus dem Studio nicht auf Produktionsdaten zugreifen, was es Ihnen ermöglicht, Speicher für Daten und neue Funktionen sicher zu testen, bevor Sie in die Produktion gehen.

Die Tests im Studio haben die gleichen Grenzen und Quoten wie die Produktion. Bei Quoten, die auf der Anzahl der Benutzer basieren, kann das resultierende Kontingent sehr klein sein, da Sie der einzige Benutzer bei den Tests im Studio sind. Wenn Sie aus dem Studio testen, könnten Sie auch eine leicht höhere Latenz und erhöhte Fehlerquoten bemerken im Vergleich zur Verwendung in der Produktion, da einige zusätzliche Prüfungen durchgeführt werden, um den Zugriff und die Berechtigungen zu überprüfen.

Für Informationen, wie Sie einen Speicher für Daten in Live-Spielen oder beim Testen im Studio debuggen, verwenden Sie die Entwicklerkonsole.

©2026 Roblox Corporation. Roblox, das Roblox-Logo und "Powering Imagination" gehören zu unseren eingetragenen und nicht eingetragenen Markenzeichen in den USA und anderen Ländern.