Anfragen, die Sie an Datenspeicher stellen, können aufgrund schwacher Konnektivität oder anderer Probleme fehlschlagen. Um Fehler zu behandeln und Nachrichten mit einem Fehlercode zurückzugeben, wickeln Sie die Datenspeicherfunktionen in pcall() ein.
Ein fehlgeschlagener Schreibaufruf, wie UpdateAsync(), bedeutet, dass der Spielserver keine erfolgreiche Antwort erhalten hat. Es garantiert nicht immer, dass der Backend-Schreibvorgang nicht stattgefunden hat. In einigen Fehlerszenarien kann der endgültige Schreibzustand dem Aufrufer unbekannt sein, bis dies mit einem nachfolgenden Lesevorgang ohne Cache verifiziert wird.
Fehlercode-Referenz
| Fehlercode | Fehlername | Fehlermeldung | Bemerkungen | |
|---|---|---|---|---|
| 101 | KeyNameEmpty | Der Schlüsselname darf nicht leer sein. | Überprüfen Sie, ob der in die Datenspeicherfunktion eingegebene Schlüssel ein leerer String ist. | |
| 102 | KeyNameLimit | Der Schlüsselname überschreitet das 50-Zeichen-Limit. | Überprüfen Sie, ob der in die Datenspeicherfunktion eingegebene Schlüssel eine Länge von 50 überschreitet. | |
| 103 | ValueNotAllowed | Kann X in DataStore nicht zulassen. | Eine fehlerhafte Aktualisierungsfunktion hat einen Wert vom Typ X zurückgegeben. | |
| 104 | CantStoreValue | Kann X in DataStore nicht speichern. | Die Aktualisierungsfunktion hat einen Wert vom Typ X zurückgegeben, der nicht serialisiert werden konnte. | |
| 105 | ValueTooLarge | Der serialisierte Wert überschreitet das X Limit. | Wenn Sie einen Wert mit SetAsync() oder UpdateAsync() festlegen, darf die serielle Länge des Wertes die Größe X nicht überschreiten. Um die serielle Länge der Daten zu überprüfen, verwenden Sie JSONEncode(). | |
| 106 | MaxValueInvalid | MaxValue muss eine ganze Zahl sein. | Wenn Sie einen Maximalwert an GetSortedAsync() für einen OrderedDataStore übergeben, muss dies eine ganze Zahl sein. | |
| 106 | MinValueInvalid | MinValue muss eine ganze Zahl sein. | Wenn Sie einen Minimalwert an GetSortedAsync() für einen OrderedDataStore übergeben, muss dies eine ganze Zahl sein. | |
| 106 | PageSizeGreater | PageSize muss in einem vordefinierten Bereich liegen. | Die minimale Seitenanzahl für einen OrderedDataStore beträgt 1. | |
| 106 | PageSizeLesser | PageSize muss in einem vordefinierten Bereich liegen. | Die maximale Seitenanzahl für einen OrderedDataStore beträgt 100. | |
| 107 | MinMaxOrderInvalid | MaxValue muss größer oder gleich MinValue sein. | Der Maximalwert muss größer oder gleich dem Minimalwert für GetSortedAsync() sein. | |
| 301 | GetAsyncThrottle | GetAsync Anfrage abgebrochen. Anfrage wurde gedrosselt, aber die Warteschlange war voll. | GetAsync() Anfrage hat die maximale Warteschlangenanzahl überschritten und Roblox ist nicht in der Lage, die Anfragen mit dem aktuellen Durchsatz zu verarbeiten. | |
| 302 | SetAsyncThrottle | SetAsync Anfrage abgebrochen. Anfrage wurde gedrosselt, aber die Warteschlange war voll. | SetAsync() Anfrage hat die maximale Warteschlangenanzahl überschritten und Roblox ist nicht in der Lage, die Anfragen mit dem aktuellen Durchsatz zu verarbeiten. | |
| 303 | IncreAsyncThrottle | IncrementAsync Anfrage abgebrochen. Anfrage wurde gedrosselt, aber die Warteschlange war voll. | IncrementAsync() Anfrage hat die maximale Warteschlangenanzahl überschritten und Roblox ist nicht in der Lage, die Anfragen mit dem aktuellen Durchsatz zu verarbeiten. | |
| 304 | UpdateAsyncThrottle | UpdateAsync Anfrage abgebrochen. Anfrage wurde gedrosselt, aber die Warteschlange war voll. | UpdateAsync() Anfrage hat die maximale Warteschlangenanzahl überschritten und Roblox ist nicht in der Lage, die Anfragen mit dem aktuellen Durchsatz zu verarbeiten. | |
| 304 | TransformThrottle | UpdateAsync Anfrage abgebrochen. Anfrage wurde gedrosselt, aber die Warteschlange war voll. | UpdateAsync() Anfrage hat die maximale Warteschlangenanzahl überschritten und Roblox ist nicht in der Lage, die Anfragen mit dem aktuellen Durchsatz zu verarbeiten. | |
| 305 | GetSortedThrottle | GetSorted Anfrage abgebrochen. Anfrage wurde gedrosselt, aber die Warteschlange war voll. | GetSortedAsync() Anfrage hat die maximale Warteschlangenanzahl überschritten und Roblox ist nicht in der Lage, die Anfragen mit dem aktuellen Durchsatz zu verarbeiten. | |
| 306 | RemoveAsyncThrottle | RemoveAsync Anfrage abgebrochen. Anfrage wurde gedrosselt, aber die Warteschlange war voll. | RemoveAsync() Anfrage hat die maximale Warteschlangenanzahl überschritten und Roblox ist nicht in der Lage, die Anfragen mit dem aktuellen Durchsatz zu verarbeiten. | |
| 401 | DataModelNoAccess | Anfrage fehlgeschlagen. DataModel ist nicht zugänglich, während die Erfahrung heruntergefahren wird. | DataModel ist uninitialisiert, da die Erfahrung heruntergefahren wird. | |
| 402 | LuaWebSrvsNoAccess | Anfrage fehlgeschlagen. LuaWebService ist nicht zugänglich, während die Erfahrung heruntergefahren wird. | LuaWebService ist uninitialisiert, da die Erfahrung heruntergefahren wird. | |
| 403 | StudioAccessToApisNotAllowed | Kann nicht von Studio aus in DataStore schreiben, da der API-Zugriff nicht aktiviert ist. | Der API-Zugriff muss aktiv sein, um Datenspeicher im Studio verwenden zu können. | |
| 404 | InternalError | OrderedDataStore existiert nicht. | Der OrderedDataStore, der mit dieser Anfrage verbunden ist, wurde nicht gefunden. Dies könnte ein Hinweis auf Datenkorruption sein. Versuchen Sie es später erneut. | |
| 501 | InternalError | Kann Antwort nicht parsen, da Daten möglicherweise beschädigt sind. | Der Server konnte die Antwort auf Ihre Anfrage nicht parsen. Dies könnte ein Hinweis auf Datenkorruption sein. Versuchen Sie es später erneut. | |
| 502 | RequestRejected | API-Dienste haben die Anfrage mit Fehler X abgelehnt. | Fehler X trat bei der Verarbeitung auf Roblox-Servern auf. Versuchen Sie es später erneut. | |
| 503 | InternalError | Die Anfrage an den Datenspeicher war erfolgreich, aber der Schlüssel wurde nicht gefunden. | Der angeforderte Schlüssel wurde im Datenspeicher nicht gefunden. Dies könnte ein Hinweis auf Datenkorruption sein. Versuchen Sie es später erneut. | |
| 504 | InternalError | Die Anfrage an den Datenspeicher war erfolgreich, aber die Antwort war nicht korrekt formatiert. | Der Server konnte die Antwort auf Ihre Anfrage nicht parsen. Dies könnte ein Hinweis auf Datenkorruption sein. Versuchen Sie es später erneut. | |
| 505 | InternalError | OrderedDataStore Anfrage war erfolgreich, aber die Antwort war nicht korrekt formatiert. | Der Server konnte die Antwort auf Ihre OrderedDataStore Anfrage nicht parsen. Dies könnte ein Hinweis auf Datenkorruption sein. Versuchen Sie es später erneut. | |
| 509 | OperationNotAllowed | Datenspeicheroperationen sind gesperrt, während sie auf einem Privaten RCC ausgeführt werden, um mögliche Datenkorruption zu verhindern. | Datenspeicher-Schreibvorgänge sind auf privaten RCC-Kanälen blockiert. | |
| 511 | AttributeSizeTooLarge | Die Größe der Metadatenattribute überschreitet das X Limit. | Die serielle Größe der Metadaten überschreitet das Limit von X. Der Wert X ist dynamisch. Wenn sich die Größe ändert, ändert sich auch der Wert. | |
| 512 | UserIdLimitExceeded | Die Größe von UserID überschreitet das X Limit. | Die Länge des vom Benutzer bereitgestellten Benutzer-ID-Arrays überschreitet das Limit von X. | |
| 513 | AttributeFormatError | Das Format des Attributs userId ist ungültig. | Die bereitgestellte Benutzer-ID ist keine Zahl. | |
| 513 | AttributeFormatError | Das Format der Metadatenattribute ist ungültig. | Die Metadaten sind keine Tabelle. | |
| GetVersionAsyncThrottle | GetVersionAsync Anfrage abgebrochen. Anfrage wurde gedrosselt. | GetVersionAsync() Anfrage hat die maximale Warteschlangenanzahl überschritten und Roblox ist nicht in der Lage, die Anfragen mit dem aktuellen Durchsatz zu verarbeiten. | ||
| GetVersionAtTimeAsyncThrottle | GetVersionAtTimeAsync Anfrage abgebrochen. Anfrage wurde gedrosselt. | GetVersionAtTimeAsync() Anfrage hat die maximale Warteschlangenanzahl überschritten und Roblox ist nicht in der Lage, die Anfragen mit dem aktuellen Durchsatz zu verarbeiten. | ||
| ListDataStoresAsyncThrottle | ListDataStoresAsync Anfrage abgebrochen. Anfrage wurde gedrosselt. | ListDataStoresAsync() Anfrage hat die maximale Warteschlangenanzahl überschritten und Roblox ist nicht in der Lage, die Anfragen mit dem aktuellen Durchsatz zu verarbeiten. | ||
| ListKeysAsyncThrottle | ListKeysAsync Anfrage abgebrochen. Anfrage wurde gedrosselt. | ListKeysAsync() Anfrage hat die maximale Warteschlangenanzahl überschritten und Roblox ist nicht in der Lage, die Anfragen mit dem aktuellen Durchsatz zu verarbeiten. | ||
| ListVersionsAsyncThrottle | ListVersionsAsync Anfrage abgebrochen. Anfrage wurde gedrosselt. | ListVersionsAsync() Anfrage hat die maximale Warteschlangenanzahl überschritten und Roblox ist nicht in der Lage, die Anfragen mit dem aktuellen Durchsatz zu verarbeiten. | ||
| RemoveVersionAsyncThrottle | RemoveVersionAsync Anfrage abgebrochen. Anfrage wurde gedrosselt. | RemoveVersionAsync() Anfrage hat die maximale Warteschlangenanzahl überschritten und Roblox ist nicht in der Lage, die Anfragen mit dem aktuellen Durchsatz zu verarbeiten. | ||
| InvalidTimestamp | Der Zeitstempel muss positiv sein und darf nicht mehr als zehn Minuten in der Zukunft liegen. | Der dem GetVersionAtTimeAsync() übergebene Zeitstempel war nicht gültig. | ||
| StandardReadExperienceThrottled | StandardRead Anfrage wurde durch Erfahrungsgrenzen gedrosselt. | Eine Anfrage an GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), oder das Lesen von UpdateAsync() in einem Standarddatenspeicher hat die StandardRead Erfahrungs-Rategrenze überschritten. | ||
| StandardWriteExperienceThrottled | StandardWrite Anfrage wurde durch Erfahrungsgrenzen gedrosselt. | Eine Anfrage an SetAsync(), IncrementAsync(), oder das Schreiben von UpdateAsync() in einem Standarddatenspeicher hat die StandardWrite Erfahrungs-Rategrenze überschritten. | ||
| StandardListExperienceThrottled | StandardList Anfrage wurde durch Erfahrungsgrenzen gedrosselt. | Eine Anfrage an ListKeysAsync(), ListVersionsAsync(), oder ListDataStoresAsync() in Standarddatenspeichern hat die StandardList Erfahrungs-Rategrenze überschritten. | ||
| StandardRemoveExperienceThrottled | StandardRemove Anfrage wurde durch Erfahrungsgrenzen gedrosselt. | Eine Anfrage an RemoveAsync() in einem Standarddatenspeicher hat die StandardRemove Erfahrungs-Rategrenze überschritten. | ||
| OrderedReadExperienceThrottled | OrderedRead Anfrage wurde durch Erfahrungsgrenzen gedrosselt. | Eine Anfrage an GetAsync() oder das Lesen von UpdateAsync() in einem geordneten Datenspeicher hat die OrderedRead Erfahrungs-Rategrenze überschritten. | ||
| OrderedWriteExperienceThrottled | OrderedWrite Anfrage wurde durch Erfahrungsgrenzen gedrosselt. | Eine Anfrage an SetAsync(), IncrementAsync(), oder das Schreiben von UpdateAsync() in einem geordneten Datenspeicher hat die OrderedWrite Erfahrungs-Rategrenze überschritten. | ||
| OrderedListExperienceThrottled | OrderedList Anfrage wurde durch Erfahrungsgrenzen gedrosselt. | Eine Anfrage an GetSortedAsync() in einem geordneten Datenspeicher hat die OrderedList Erfahrungs-Rategrenze überschritten. | ||
| OrderedRemoveExperienceThrottled | OrderedRemove Anfrage wurde durch Erfahrungsgrenzen gedrosselt. | Eine Anfrage an RemoveAsync() in einem geordneten Datenspeicher hat die OrderedRemove Erfahrungs-Rategrenze überschritten. | ||
| StandardReadGameServerThrottled | StandardRead Anfrage wurde durch Grenzen des Spielservers gedrosselt oder die Anfrage-Warteschlange war voll. | Eine Anfrage an GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), oder das Lesen von UpdateAsync() in einem Standarddatenspeicher hat die StandardRead Spielserver-Rategrenze überschritten. | ||
| StandardWriteGameServerThrottled | StandardWrite Anfrage wurde durch Grenzen des Spielservers gedrosselt oder die Anfrage-Warteschlange war voll. | Eine Anfrage an SetAsync(), IncrementAsync(), oder das Schreiben von UpdateAsync() in einem Standarddatenspeicher hat die StandardWrite Spielserver-Rategrenze überschritten. | ||
| StandardListGameServerThrottled | StandardList Anfrage wurde durch Grenzen des Spielservers gedrosselt oder die Anfrage-Warteschlange war voll. | Eine Anfrage an ListKeysAsync(), ListVersionsAsync(), oder ListDataStoresAsync() in Standarddatenspeichern hat die StandardList Spielserver-Rategrenze überschritten. | ||
| StandardRemoveGameServerThrottled | StandardRemove Anfrage wurde durch Grenzen des Spielservers gedrosselt oder die Anfrage-Warteschlange war voll. | Eine Anfrage an RemoveAsync() in einem Standarddatenspeicher hat die StandardRemove Spielserver-Rategrenze überschritten. | ||
| OrderedReadGameServerThrottled | OrderedRead Anfrage wurde durch Grenzen des Spielservers gedrosselt oder die Anfrage-Warteschlange war voll. | Eine Anfrage an GetAsync() oder das Lesen von UpdateAsync() in einem geordneten Datenspeicher hat die OrderedRead Spielserver-Rategrenze überschritten. | ||
| OrderedWriteGameServerThrottled | OrderedWrite Anfrage wurde durch Grenzen des Spielservers gedrosselt oder die Anfrage-Warteschlange war voll. | Eine Anfrage an SetAsync(), IncrementAsync(), oder das Schreiben von UpdateAsync() in einem geordneten Datenspeicher hat die OrderedWrite Spielserver-Rategrenze überschritten. | ||
| OrderedListGameServerThrottled | OrderedList Anfrage wurde durch Grenzen des Spielservers gedrosselt oder die Anfrage-Warteschlange war voll. | Eine Anfrage an GetSortedAsync() in einem geordneten Datenspeicher hat die OrderedList Spielserver-Rategrenze überschritten. | ||
| OrderedRemoveGameServerThrottled | OrderedRemove Anfrage wurde durch Grenzen des Spielservers gedrosselt oder die Anfrage-Warteschlange war voll. | Eine Anfrage an RemoveAsync() in einem geordneten Datenspeicher hat die OrderedRemove Spielserver-Rategrenze überschritten. |
Serverfehlercodes
| Fehlername | Fehlermeldung | Bemerkungen |
|---|---|---|
| DatastoreDeleted | Der Datenspeicher wurde gelöscht. | Eine Operation am Datenspeicher konnte nicht durchgeführt werden, weil der Datenspeicher zuvor gelöscht wurde. |
| DatastoreThrottled | Die Anfragegeschwindigkeit überschreitet das zulässige Maximum für den datastore. | Zu viele Anfragen wurden an einen einzelnen Datenspeicher gesendet. |
| InternalServerError | Es trat ein interner Serverfehler auf. | Gelegentlicher Fehler auf Roblox-Servern. Versuchen Sie es erneut, idealerweise mit exponentiellem Backoff. |
| InvalidExclusiveStartKey | Der bereitgestellte exklusive Startschlüssel ist ungültig. | Der bereitgestellte exklusive Startschlüssel (Cursor) für eine Listenoperation wie ListKeysAsync() ist ungültig. |
| InvalidPlace | Der bereitgestellte Platz ist ungültig. | Keine Übereinstimmung mit der Universum-ID für den Platz. Versuchen Sie es später erneut. |
| InvalidTarget | Das bereitgestellte Ziel ist ungültig. | Der Schlüsselname des geordneten Datenspeichers überschreitet das 50-Zeichen-Limit. |
| InvalidUniverse | Das bereitgestellte Universum ist ungültig. | Keine Übereinstimmung mit der Platz-ID für das Universum. Versuchen Sie es später erneut. |
| InvalidUserIds | Die bereitgestellten Benutzer-IDs haben ein ungültiges Format. | Beim Parsen der Benutzer-IDs ist ein Fehler aufgetreten. |
| KeyThrottled | Die Anfragegeschwindigkeit überschreitet das zulässige Maximum für den Schlüssel. | Die Anfragegeschwindigkeit überschreitet die maximal zulässige Anfragegeschwindigkeit für einen einzelnen Schlüssel. |
| KeyNotFound | Der angeforderte Schlüssel existiert nicht. | Der Schlüssel existiert nicht. |
| N/A | Es gibt keine Seiten, zu denen weitergegangen werden kann. | Dieser Fehler tritt auf, wenn Sie Pages:AdvanceToNextPageAsync() auf der letzten Seite aufrufen. |
| StandardReadExperienceThrottled | Die Standardleseanfragegeschwindigkeit überschreitet das zulässige Maximum für die Erfahrung. | Eine Anfrage an GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), oder das Lesen von UpdateAsync() in einem Standarddatenspeicher hat die StandardRead Erfahrungs-Rategrenze überschritten. |
| StandardWriteExperienceThrottled | Die Standard-Schreibanfragegeschwindigkeit überschreitet das zulässige Maximum für die Erfahrung. | Eine Anfrage an SetAsync(), IncrementAsync(), oder das Schreiben von UpdateAsync() in einem Standarddatenspeicher hat die StandardWrite Erfahrungs-Rategrenze überschritten. |
| StandardListExperienceThrottled | Die Standardauflistungsanfragegeschwindigkeit überschreitet das zulässige Maximum für die Erfahrung. | Eine Anfrage an ListKeysAsync(), ListVersionsAsync(), oder ListDataStoresAsync() in Standarddatenspeichern hat die StandardList Erfahrungs-Rategrenze überschritten. |
| StandardRemoveExperienceThrottled | Die Standardentfernungsanfragegeschwindigkeit überschreitet das zulässige Maximum für die Erfahrung. | Eine Anfrage an RemoveAsync() in einem Standarddatenspeicher hat die StandardRemove Erfahrungs-Rategrenze überschritten. |
| OrderedReadExperienceThrottled | Die geordnete Leseanfragegeschwindigkeit überschreitet das zulässige Maximum für die Erfahrung. | Eine Anfrage an GetAsync() oder das Lesen von UpdateAsync() in einem geordneten Datenspeicher hat die OrderedRead Erfahrungs-Rategrenze überschritten. |
| OrderedWriteExperienceThrottled | Die geordnete Schreibanfragegeschwindigkeit überschreitet das zulässige Maximum für die Erfahrung. | Eine Anfrage an SetAsync(), IncrementAsync(), oder das Schreiben von UpdateAsync() in einem geordneten Datenspeicher hat die OrderedWrite Erfahrungs-Rategrenze überschritten. |
| OrderedListExperienceThrottled | Die geordnete Listenanfragegeschwindigkeit überschreitet das zulässige Maximum für die Erfahrung. | Eine Anfrage an GetSortedAsync() in einem geordneten Datenspeicher hat die OrderedList Erfahrungs-Rategrenze überschritten. |
| OrderedRemoveExperienceThrottled | Die geordnete Entfernenanfragegeschwindigkeit überschreitet das zulässige Maximum für die Erfahrung. | Eine Anfrage an RemoveAsync() in einem geordneten Datenspeicher hat die OrderedRemove Erfahrungs-Rategrenze überschritten. |
Grenzen
Datenmodelle haben Grenzen. Wenn eine Erfahrung diese Grenzen überschreitet, drosselt der Dienst automatisch die Nutzung des Datenspeichers der Erfahrung und sorgt dafür, dass zukünftige Anfragen in eine der folgenden Warteschlangen eingeordnet werden:
- Set
- Geordnetes Set
- Get
- Geordnetes Get
Anfragen in einer Warteschlange werden in der Reihenfolge bearbeitet, in der sie empfangen wurden. Die aufgerufene Funktion gibt weiterhin die Kontrolle ab, solange ihre Anfrage noch in der Warteschlange ist. Wenn der Datenspeicherschlüssel selbst gedrosselt wird, wird die Anfrage in eine Warteschlange eingeordnet, aber vorübergehend übersprungen.
Jede Warteschlange hat ein Limit von 30 Anfragen. Wenn das Limit einer Warteschlange erreicht ist, schlägt die Anfrage mit einem Fehlercode im Bereich von 301-306 fehl, was darauf hinweist, dass die Anfragen vollständig abgebrochen wurden.
Zugriffslimits
Datenspeicher unterliegen sowohl Erfahrungs- als auch Server-Limits. Die Erfahrungs-Limits skalieren mit der Gesamtanzahl der gleichzeitigen Benutzer in der Erfahrung, während die Server-Limits konfigurierbar sind und als Werkzeug für den Ersteller gedacht sind.
Erfahrungs-Limits
Jede Erfahrung darf eine bestimmte Anzahl von Datenspeicheranfragen basierend auf dem Datenspeichertyp, dem Anfrage-Typ und der Anzahl gleichzeitiger Benutzer haben. Für jeden Datenspeichertyp und Anfrage-Typ wird das Limit unter allen aufgeführten Funktionen geteilt.
- UpdateAsync() verbraucht sowohl das Lese- als auch das Schreibbudget. Ein einzelner Aufruf verringert beide Limits.
- Spielserver und Open Cloud teilen ein Budget; Open Cloud-Verkehr kann durch die Nutzung in der Erfahrung (und umgekehrt) gedrosselt werden. Siehe Steuerung von Ratenlimits für weitere Hinweise.
Standarddatenspeicher
| Anfrage-Typ | Spielserver-API | Open Cloud-API | Geteilte Limits (Anfragen pro Minute) |
|---|---|---|---|
| Lesen | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() UpdateAsync() | Datenspeichereintrag abrufen | 300 + gleichzeitigeBenutzer × 40 |
| Schreiben | SetAsync() IncrementAsync() UpdateAsync() | Erstellen, Aktualisieren, Erhöhen des Datenspeichereintrags | 300 + gleichzeitigeBenutzer × 20 |
| Auflisten | ListDataStoresAsync() ListKeysAsync() ListVersionsAsync() | Datenspeicher auflisten, Datenspeichereinträge auflisten, Revisionen von Datenspeichereinträgen auflisten | 300 + gleichzeitigeBenutzer × 2 |
| Entfernen | RemoveAsync() | Datenspeichereintrag löschen, Datenspeicher löschen, Datenspeicher wiederherstellen | 300 + gleichzeitigeBenutzer × 40 |
Geordnete Datenspeicher
| Anfrage-Typ | Spielserver-API | Open Cloud-API | Geteilte Limits (Anfragen pro Minute) |
|---|---|---|---|
| Lesen | GetAsync() UpdateAsync() | Geordneten Datenspeichereintrag abrufen | 300 + gleichzeitigeBenutzer × 40 |
| Schreiben | SetAsync() IncrementAsync() UpdateAsync() | Erstellen, Aktualisieren, Erhöhen des geordneten Datenspeichereintrags | 300 + gleichzeitigeBenutzer × 20 |
| Auflisten | GetSortedAsync() | Geordnete Datenspeichereinträge auflisten | 300 + gleichzeitigeBenutzer × 2 |
| Entfernen | RemoveAsync() | Geordneten Datenspeichereintrag löschen | 300 + gleichzeitigeBenutzer × 40 |
Steuerung von Ratenlimits
Da Open Cloud- und Spielserveranfragen geteilt werden, ist es wichtig, unabhängig zu steuern, wie viel jeder davon verbrauchen kann.
Spielserver
Einzelne Server haben integrierte Limits, wie oben beschrieben. Verwenden Sie eine Kombination aus SetRateLimitForRequestType() und GetRequestBudgetForRequestType(), um eine präzise Kontrolle über den Beitrag der einzelnen Server zum Gesamthaushalt zu erhalten.
Open Cloud
Open Cloud-Anfragen erfordern eine externe Ratenbegrenzungslösung. Wir empfehlen einen der folgenden Ansätze:
- (Einfach) Fügen Sie nach jeder Anfrage eine kurze Verzögerung hinzu, insbesondere wenn Sie in einer kontinuierlichen Schleife dieselbe API aufrufen. Setzen Sie diese Verzögerung auf 60 / (gewünschter Budgetverbrauch pro Minute) Sekunden, als obere Grenze. Beachten Sie, dass dieser Ansatz keine Anfragen in Spitzenzeiten zulässt.
- (Robust) Implementieren Sie einen lokalen Ratenbegrenzer mit der leaky bucket-Strategie.
Die folgenden Node.js-Codebeispiele enthalten Referenzimplementierungen.
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error('Die Umgebungsvariable API_KEY ist nicht gesetzt.');
}
const apiHeaderKey = 'x-api-key';
const universeId = '';
const dataStoreId = 'Inventory';
const baseUrl = 'https://apis.roblox.com/cloud/v2/';
// --- Konfiguration der Ratenbegrenzung pro Operation (Anfragen pro Minute) ---
const LIST_RATE_PER_MIN = 60;
const GET_RATE_PER_MIN = 120;
const UPDATE_RATE_PER_MIN = 60;
// Obergrenzenabstand pro Operation: 60 / (Anfragen pro Minute) Sekunden.
const LIST_INTERVAL_MS = (60 / LIST_RATE_PER_MIN) * 1000;
const GET_INTERVAL_MS = (60 / GET_RATE_PER_MIN) * 1000;
const UPDATE_INTERVAL_MS = (60 / UPDATE_RATE_PER_MIN) * 1000;
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
// Führt die Anfrage aus und wartet dann auf das Intervall dieser Operation, bevor es zurückkehrt.
async function throttledFetch(url, options, intervalMs) {
const response = await fetch(url, options);
await sleep(intervalMs);
return response;
}
async function listEntries(universe, dataStore) {
const listPath = `universes/${universe}/data-stores/${dataStore}/entries`;
const url = baseUrl + listPath;
const response = await throttledFetch(url, {
headers: { [apiHeaderKey]: apiKey }
}, LIST_INTERVAL_MS);
return response.json();
}
async function getEntry(path) {
const url = baseUrl + path;
const response = await throttledFetch(url, {
headers: { [apiHeaderKey]: apiKey }
}, GET_INTERVAL_MS);
return response.json();
}
async function updateEntry(path, payload) {
const url = baseUrl + path;
const response = await throttledFetch(url, {
method: 'PATCH',
headers: {
[apiHeaderKey]: apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload) // Der Body muss ein String sein
}, UPDATE_INTERVAL_MS);
return response;
}
(async () => {
try {
const entries = await listEntries(universeId, dataStoreId);
for (const entry of entries.dataStoreEntries) {
const path = entry.path;
console.log(`\nVerarbeite Eintrag: ${path}`);
const currentData = await getEntry(path);
currentData.value.currency += 10;
const payload = { value: currentData.value };
const updateResponse = await updateEntry(path, payload);
console.log(`Status: ${updateResponse.status}`);
console.log(`Antwort: ${await updateResponse.text()}`);
}
} catch (error) {
console.error('Es trat ein Fehler während der Ausführung auf:', error);
}
})();Serverlimits
Jeder Server hat ein konfigurierbares Ratenlimit für jeden Anfrage-Typ, basierend auf der Anzahl der Spieler auf diesem Server. Server erhalten beim ersten Start einen einmaligen Anstieg des zusätzlichen Anfragebudgets. Verwenden Sie GetRequestBudgetForRequestType(), um die Anzahl der Datenspeicheranfragen zu bestätigen, die der aktuelle Server zu einem beliebigen Zeitpunkt durchführen kann.
Diese Limits sind konfigurierbar durch den Ersteller mit der SetRateLimitForRequestType() API. Mit dieser API kann ein Ersteller die Ratenlimits seiner eigenen Datenspeicher für jeden Anfrage-Typ konfigurieren.
Die folgenden Standard-Ratenlimits gelten, wenn die API nicht aufgerufen wird:
Standarddatenspeicher
| Anfrage-Typ | DataStoreRequestType Enum | Spielserver-API | Anfragen pro Minute |
|---|---|---|---|
| Lesen | StandardRead | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() UpdateAsync() | 60 + numPlayers × 40 |
| Schreiben | StandardWrite | SetAsync() IncrementAsync() UpdateAsync() | 60 + numPlayers × 40 |
| Auflisten | StandardList | ListDataStoresAsync() ListKeysAsync() ListVersionsAsync() | 5 + numPlayers × 2 |
| Entfernen | StandardRemove | RemoveAsync() | 60 + numPlayers × 40 |
| RemoveVersion (Veraltet) | RemoveVersionAsync | RemoveVersionAsync() | 5 + numPlayers × 2 |
Geordnete Datenspeicher
| Anfrage-Typ | DataStoreRequestType Enum | Spielserver-API | Anfragen pro Minute |
|---|---|---|---|
| Lesen | OrderedRead | GetAsync() UpdateAsync() | 60 + numPlayers × 40 |
| Schreiben | OrderedWrite | SetAsync() IncrementAsync() UpdateAsync() | 30 + numPlayers × 5 |
| Auflisten | OrderedList | GetSortedAsync() | 5 + numPlayers × 2 |
| Entfernen | OrderedRemove | RemoveAsync() | 30 + numPlayers × 5 |
Datenlimits
Datenspeicher begrenzen, wie viele Daten pro Eintrag verwendet werden können.
Der Name des Datenspeichers, der Schlüsselname und der Umfang müssen alle eine bestimmte Zeichenlänge nicht überschreiten. Verwenden Sie string.len(), um ihre Länge zu überprüfen.
Die Daten (Schlüsselwert) werden auch als String gespeichert, unabhängig von ihrem ursprünglichen Typ. Sie können die Größe der Daten mit der Funktion JSONEncode() überprüfen, die Luau-Daten in eine serialisierte JSON-Tabelle umwandelt.
| Komponente | Maximale Anzahl von Zeichen |
|---|---|
| Name des Datenspeichers | 50 |
| Schlüsselname | 50 |
| Umfang | 50 |
| Daten (Schlüsselwert) | 4.194.304 pro Schlüssel |
Metadatenlimits
Limits für die Anzahl von Zeichen in benutzerdefinierten Metadaten.
| Komponente | Maximale Anzahl von Zeichen |
|---|---|
| Schlüsselname | 50 |
| Wert | 250 |
| Schlüssel-Wert-Paare | 300 |
Durchsatzlimits
Pro-Schlüssel-Durchsatzlimits stellen sicher, dass die Leistung auf Roblox-Servern optimal ist. Jedes Limit gilt für jeden einzelnen Schlüssel über alle Server in einer Erfahrung und erfrischt sich im Laufe der Zeit.
Roblox untersucht die Nutzung des mit dem Schlüssel verbundenen Kontingents über die letzten 60 Sekunden. Wenn die Nutzung, einschließlich der aktuellen Anfrage, innerhalb des Durchsatzlimits liegt, wird die Anfrage genehmigt. Wenn die Nutzung das Limit überschreitet, wird die Anfrage abgelehnt.
| Anfrage-Typ | Spielserver-API | Open Cloud-API | Limit |
|---|---|---|---|
| Lesen | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() ListVersionsAsync() UpdateAsync() | Datenspeichereintrag abrufen | 25 MB pro Minute |
| Schreiben | SetAsync() IncrementAsync() UpdateAsync() RemoveAsync() | Erstellen, Aktualisieren, Erhöhen, Entfernen Datenspeichereintrag | 4 MB pro Minute |
Neben den oben genannten Durchsatzlimits organisiert Roblox Daten in Partitionen basierend auf einem internen Schema. Wenn der Backend-Server daher ein hohes Volumen an Anfragen an denselben Datenspeicher erhält, kann dies zu weiterer Drosselung führen. Unabhängig von der Ursache manifestiert sich die Drosselung entweder als DatastoreThrottled- oder KeyThrottled-Fehler, je nachdem, ob das Durchsatzlimit für einen einzelnen Datenspeicher oder einen Schlüssel überschritten wurde. Diese Fehlermeldungen gelten sowohl für geordnete als auch für standardmäßige Datenspeicher.
Speicherlimits
Um die Speicherung stabil und skalierbar zu halten, nutzen Datenspeicher ein spielbasiertes Limit für Ihre Speichernutzung.
Dieses Limit besteht aus einer Grundzuweisung für jedes Spiel plus einer zusätzlichen Zuweisung basierend auf der Anzahl der Lebensnutzer. Ein Lebensnutzer ist jeder Benutzer, der Ihr Spiel mindestens einmal betreten hat.
Das Speicherlimit wird mit der folgenden Formel berechnet: Gesamtes Speicherlimit der neuesten Version = 500 MB + 1 MB × Lebensbenutzeranzahl.
Die Speichernutzung wird anhand der komprimierten Größe der neuesten Version jedes Schlüssels gemessen. Datenspeicher komprimieren Ihre Daten automatisch vor der Speicherung, also vermeiden Sie es, sie selbst vorab zu komprimieren. Die Vorabkomprimierung erhöht die unnötige CPU-Last und kann die Effektivität der integrierten Kompression von Datenspeichern verringern. Indem Sie unkomprimierte Daten speichern, profitieren Sie automatisch von Verbesserungen der Kompressionsalgorithmen von Roblox und zukünftigen schema-basierten Optimierungen.
Nur die neueste Version jedes Schlüssels zählt zu Ihrer Speichernutzung. Gelöschte Schlüssel und überholte Versionen, die während ihrer Aufbewahrungsfrist weiterhin über die Versions-APIs zugänglich sind, zählen nicht zu Ihrer Speichernutzung. Datenspeicher, die über die Open Cloud DeleteDataStore Methode gelöscht wurden, zählen jedoch während ihrer 30-tägigen Löschbearbeitungszeit weiterhin zur Speichernutzung, bis sie dauerhaft entfernt werden.