Anfragen, die Sie an Datenspeicher stellen, können aufgrund schlechter Konnektivität oder anderer Probleme fehlschlagen. Um Fehler zu behandeln und Nachrichten mit einem Fehlercode zurückzugeben, wickeln Sie Datenspeicherfunktionen in pcall() ein.
Ein fehlgeschlagener Schreibaufruf, wie UpdateAsync(), bedeutet, dass der Spieleserver keine erfolgreiche Antwort erhalten hat. Es garantiert nicht immer, dass der Backend-Schreibvorgang nicht stattgefunden hat. In einigen Fehlerszenarien kann der endgültige Schreibstatus dem Aufrufer unbekannt sein, bis er mit einem nachfolgenden Lesevorgang ohne Cache überprüft wird.
Fehlercode-Referenz
| Fehlercode | Fehlername | Fehlermeldung | Hinweise | |
|---|---|---|---|---|
| 101 | KeyNameEmpty | Der Schlüsselname darf nicht leer sein. | Überprüfen Sie, ob der Schlüssel, der in die Datenspeicherfunktion eingegeben wurde, eine leere Zeichenfolge ist. | |
| 102 | KeyNameLimit | Der Schlüsselname überschreitet das Limit von 50 Zeichen. | Überprüfen Sie, ob der Schlüssel, der in die Datenspeicherfunktion eingegeben wurde, 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 | Serialisierter Wert überschreitet das Limit von X. | Wenn Sie einen Wert mit SetAsync() oder UpdateAsync() festlegen, darf die serialisierte Länge des Wertes das Limit von X nicht überschreiten. Um die serialisierte Länge der Daten zu überprüfen, verwenden Sie JSONEncode(). | |
| 106 | MaxValueInvalid | MaxValue muss eine Ganzzahl sein. | Wenn Sie einen Maximalwert an GetSortedAsync() für einen OrderedDataStore übergeben, muss er eine Ganzzahl sein. | |
| 106 | MinValueInvalid | MinValue muss eine Ganzzahl sein. | Wenn Sie einen Minimalwert an GetSortedAsync() für einen OrderedDataStore übergeben, muss er eine Ganzzahl sein. | |
| 106 | PageSizeGreater | PageSize muss innerhalb eines vordefinierten Bereichs liegen. | Die minimale Seitenzahl für einen OrderedDataStore beträgt 1. | |
| 106 | PageSizeLesser | PageSize muss innerhalb eines vordefinierten Bereichs liegen. | Die maximale Seitenzahl 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 abgelehnt. Anfrage wurde gedrosselt, aber die Warteschlange war voll. | GetAsync()-Anfrage hat die maximale Warteschlangengröße überschritten und Roblox kann die Anfragen bei der aktuellen Durchsatzrate nicht verarbeiten. | |
| 302 | SetAsyncThrottle | SetAsync-Anfrage abgelehnt. Anfrage wurde gedrosselt, aber die Warteschlange war voll. | SetAsync()-Anfrage hat die maximale Warteschlangengröße überschritten und Roblox kann die Anfragen bei der aktuellen Durchsatzrate nicht verarbeiten. | |
| 303 | IncreAsyncThrottle | IncrementAsync-Anfrage abgelehnt. Anfrage wurde gedrosselt, aber die Warteschlange war voll. | IncrementAsync()-Anfrage hat die maximale Warteschlangengröße überschritten und Roblox kann die Anfragen bei der aktuellen Durchsatzrate nicht verarbeiten. | |
| 304 | UpdateAsyncThrottle | UpdateAsync-Anfrage abgelehnt. Anfrage wurde gedrosselt, aber die Warteschlange war voll. | UpdateAsync()-Anfrage hat die maximale Warteschlangengröße überschritten und Roblox kann die Anfragen bei der aktuellen Durchsatzrate nicht verarbeiten. | |
| 304 | TransformThrottle | UpdateAsync-Anfrage abgelehnt. Anfrage wurde gedrosselt, aber die Warteschlange war voll. | UpdateAsync()-Anfrage hat die maximale Warteschlangengröße überschritten und Roblox kann die Anfragen bei der aktuellen Durchsatzrate nicht verarbeiten. | |
| 305 | GetSortedThrottle | GetSorted-Anfrage abgelehnt. Anfrage wurde gedrosselt, aber die Warteschlange war voll. | GetSortedAsync()-Anfrage hat die maximale Warteschlangengröße überschritten und Roblox kann die Anfragen bei der aktuellen Durchsatzrate nicht verarbeiten. | |
| 306 | RemoveAsyncThrottle | RemoveAsync-Anfrage abgelehnt. Anfrage wurde gedrosselt, aber die Warteschlange war voll. | RemoveAsync()-Anfrage hat die maximale Warteschlangengröße überschritten und Roblox kann die Anfragen bei der aktuellen Durchsatzrate nicht verarbeiten. | |
| 401 | DataModelNoAccess | Anfrage fehlgeschlagen. DataModel ist nicht zugänglich, während die Erfahrung heruntergefahren wird. | DataModel ist nicht initialisiert, da die Erfahrung heruntergefahren wird. | |
| 402 | LuaWebSrvsNoAccess | Anfrage fehlgeschlagen. LuaWebService ist nicht zugänglich, während die Erfahrung heruntergefahren wird. | LuaWebService ist nicht initialisiert, da die Erfahrung heruntergefahren wird. | |
| 403 | StudioAccessToApisNotAllowed | Kann nicht aus dem Studio auf DataStore schreiben, da der API-Zugriff nicht aktiviert ist. | Der API-Zugriff muss aktiv sein, um Datenspeicher im Studio zu verwenden. | |
| 404 | InternalError | OrderedDataStore existiert nicht. | Der OrderedDataStore, der mit dieser Anfrage verbunden ist, wurde nicht gefunden. Dies könnte ein Zeichen für Datenkorruption sein. Versuchen Sie es später erneut. | |
| 501 | InternalError | Kann die Antwort nicht analysieren, da die Daten möglicherweise beschädigt sind. | Der Server konnte die Antwort auf Ihre Anfrage nicht analysieren. Dies könnte ein Zeichen für Datenkorruption sein. Versuchen Sie es später erneut. | |
| 502 | RequestRejected | API-Dienste haben die Anfrage mit dem Fehler X abgelehnt. | Fehler X trat bei der Verarbeitung auf den Roblox-Servern auf. Versuchen Sie es später erneut. | |
| 503 | InternalError | Die Datenspeicheranfrage war erfolgreich, aber der Schlüssel wurde nicht gefunden. | Der angeforderte Schlüssel wurde im Datenspeicher nicht gefunden. Dies könnte ein Zeichen für Datenkorruption sein. Versuchen Sie es später erneut. | |
| 504 | InternalError | Die Datenspeicheranfrage war erfolgreich, aber die Antwort war nicht korrekt formatiert. | Der Server konnte die Antwort auf Ihre Anfrage nicht analysieren. Dies könnte ein Zeichen für 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 analysieren. Dies könnte ein Zeichen für Datenkorruption sein. Versuchen Sie es später erneut. | |
| 509 | OperationNotAllowed | Datenspeicheroperationen sind während der Ausführung auf einem persönlichen RCC blockiert, um mögliche Datenkorruption zu verhindern. | Datenspeicher-Schreibvorgänge sind auf privaten RCC-Kanälen blockiert. | |
| 511 | AttributeSizeTooLarge | Die Größe des Metadatenattributs überschreitet das Limit von X. | Die serialisierte Metadatengröße ü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 Limit von X. | Die Länge des von dem 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 Attributmetadaten ist ungültig. | Die Metadaten sind keine Tabelle. | |
| GetVersionAsyncThrottle | GetVersionAsync-Anfrage abgelehnt. Anfrage wurde gedrosselt. | GetVersionAsync()-Anfrage hat die maximale Warteschlangengröße überschritten und Roblox kann die Anfragen bei der aktuellen Durchsatzrate nicht verarbeiten. | ||
| GetVersionAtTimeAsyncThrottle | GetVersionAtTimeAsync-Anfrage abgelehnt. Anfrage wurde gedrosselt. | GetVersionAtTimeAsync()-Anfrage hat die maximale Warteschlangengröße überschritten und Roblox kann die Anfragen bei der aktuellen Durchsatzrate nicht verarbeiten. | ||
| ListDataStoresAsyncThrottle | ListDataStoresAsync-Anfrage abgelehnt. Anfrage wurde gedrosselt. | ListDataStoresAsync()-Anfrage hat die maximale Warteschlangengröße überschritten und Roblox kann die Anfragen bei der aktuellen Durchsatzrate nicht verarbeiten. | ||
| ListKeysAsyncThrottle | ListKeysAsync-Anfrage abgelehnt. Anfrage wurde gedrosselt. | ListKeysAsync()-Anfrage hat die maximale Warteschlangengröße überschritten und Roblox kann die Anfragen bei der aktuellen Durchsatzrate nicht verarbeiten. | ||
| ListVersionsAsyncThrottle | ListVersionsAsync-Anfrage abgelehnt. Anfrage wurde gedrosselt. | ListVersionsAsync()-Anfrage hat die maximale Warteschlangengröße überschritten und Roblox kann die Anfragen bei der aktuellen Durchsatzrate nicht verarbeiten. | ||
| RemoveVersionAsyncThrottle | RemoveVersionAsync-Anfrage abgelehnt. Anfrage wurde gedrosselt. | RemoveVersionAsync()-Anfrage hat die maximale Warteschlangengröße überschritten und Roblox kann die Anfragen bei der aktuellen Durchsatzrate nicht verarbeiten. | ||
| InvalidTimestamp | Der Zeitstempel muss positiv sein und darf nicht mehr als zehn Minuten in der Zukunft liegen. | Der Zeitstempel, der an GetVersionAtTimeAsync() übergeben wurde, war nicht gültig. | ||
| StandardReadExperienceThrottled | StandardRead-Anfrage wurde durch Erfahrungslimits gedrosselt. | Eine Anfrage an GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), oder das Lesen von UpdateAsync() auf einem Standard-Datenspeicher hat das StandardRead-Erfahrungsratenlimit überschritten. | ||
| StandardWriteExperienceThrottled | StandardWrite-Anfrage wurde durch Erfahrungslimits gedrosselt. | Eine Anfrage an SetAsync(), IncrementAsync(), oder das Schreiben von UpdateAsync() auf einem Standard-Datenspeicher hat das StandardWrite-Erfahrungsratenlimit überschritten. | ||
| StandardListExperienceThrottled | StandardList-Anfrage wurde durch Erfahrungslimits gedrosselt. | Eine Anfrage an ListKeysAsync(), ListVersionsAsync(), oder ListDataStoresAsync() auf Standard-Datenspeichern hat das StandardList-Erfahrungsratenlimit überschritten. | ||
| StandardRemoveExperienceThrottled | StandardRemove-Anfrage wurde durch Erfahrungslimits gedrosselt. | Eine Anfrage an RemoveAsync() auf einem Standard-Datenspeicher hat das StandardRemove-Erfahrungsratenlimit überschritten. | ||
| OrderedReadExperienceThrottled | OrderedRead-Anfrage wurde durch Erfahrungslimits gedrosselt. | Eine Anfrage an GetAsync(), BatchGetAsync(), oder das Lesen von UpdateAsync() auf einem geordneten Datenspeicher hat das OrderedRead-Erfahrungsratenlimit überschritten. | ||
| OrderedWriteExperienceThrottled | OrderedWrite-Anfrage wurde durch Erfahrungslimits gedrosselt. | Eine Anfrage an SetAsync(), IncrementAsync(), oder das Schreiben von UpdateAsync() auf einem geordneten Datenspeicher hat das OrderedWrite-Erfahrungsratenlimit überschritten. | ||
| OrderedListExperienceThrottled | OrderedList-Anfrage wurde durch Erfahrungslimits gedrosselt. | Eine Anfrage an GetSortedAsync() auf einem geordneten Datenspeicher hat das OrderedList-Erfahrungsratenlimit überschritten. | ||
| OrderedRemoveExperienceThrottled | OrderedRemove-Anfrage wurde durch Erfahrungslimits gedrosselt. | Eine Anfrage an RemoveAsync() auf einem geordneten Datenspeicher hat das OrderedRemove-Erfahrungsratenlimit überschritten. | ||
| StandardReadGameServerThrottled | StandardRead-Anfrage wurde durch Spieleserverlimits gedrosselt oder die Anfragewarteschlange war voll. | Eine Anfrage an GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), oder das Lesen von UpdateAsync() auf einem Standard-Datenspeicher hat das StandardRead-Spieleserver-Ratenlimit überschritten. | ||
| StandardWriteGameServerThrottled | StandardWrite-Anfrage wurde durch Spieleserverlimits gedrosselt oder die Anfragewarteschlange war voll. | Eine Anfrage an SetAsync(), IncrementAsync(), oder das Schreiben von UpdateAsync() auf einem Standard-Datenspeicher hat das StandardWrite-Spieleserver-Ratenlimit überschritten. | ||
| StandardListGameServerThrottled | StandardList-Anfrage wurde durch Spieleserverlimits gedrosselt oder die Anfragewarteschlange war voll. | Eine Anfrage an ListKeysAsync(), ListVersionsAsync(), oder ListDataStoresAsync() auf Standard-Datenspeichern hat das StandardList-Spieleserver-Ratenlimit überschritten. | ||
| StandardRemoveGameServerThrottled | StandardRemove-Anfrage wurde durch Spieleserverlimits gedrosselt oder die Anfragewarteschlange war voll. | Eine Anfrage an RemoveAsync() auf einem Standard-Datenspeicher hat das StandardRemove-Spieleserver-Ratenlimit überschritten. | ||
| OrderedReadGameServerThrottled | OrderedRead-Anfrage wurde durch Spieleserverlimits gedrosselt oder die Anfragewarteschlange war voll. | Eine Anfrage an GetAsync(), BatchGetAsync(), oder das Lesen von UpdateAsync() auf einem geordneten Datenspeicher hat das OrderedRead-Spieleserver-Ratenlimit überschritten. | ||
| OrderedWriteGameServerThrottled | OrderedWrite-Anfrage wurde durch Spieleserverlimits gedrosselt oder die Anfragewarteschlange war voll. | Eine Anfrage an SetAsync(), IncrementAsync(), oder das Schreiben von UpdateAsync() auf einem geordneten Datenspeicher hat das OrderedWrite-Spieleserver-Ratenlimit überschritten. | ||
| OrderedListGameServerThrottled | OrderedList-Anfrage wurde durch Spieleserverlimits gedrosselt oder die Anfragewarteschlange war voll. | Eine Anfrage an GetSortedAsync() auf einem geordneten Datenspeicher hat das OrderedList-Spieleserver-Ratenlimit überschritten. | ||
| OrderedRemoveGameServerThrottled | OrderedRemove-Anfrage wurde durch Spieleserverlimits gedrosselt oder die Anfragewarteschlange war voll. | Eine Anfrage an RemoveAsync() auf einem geordneten Datenspeicher hat das OrderedRemove-Spieleserver-Ratenlimit überschritten. |
Serverfehlercodes
| Fehlername | Fehlermeldung | Hinweise |
|---|---|---|
| DatastoreDeleted | Der Datenspeicher wurde gelöscht. | Eine Operation auf dem Datenspeicher konnte nicht durchgeführt werden, da der Datenspeicher zuvor gelöscht wurde. |
| DatastoreThrottled | Die Anfragerate überschreitet das zulässige Maximum für den datastore. | Zu viele Anfragen wurden an einen einzelnen Datenspeicher gesendet. |
| InternalServerError | Ein interner Serverfehler ist aufgetreten. | Gelegentlicher Fehler auf den 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 Ort ist ungültig. | Keine übereinstimmende Universum-ID für den Ort. Versuchen Sie es später erneut. |
| InvalidTarget | Das bereitgestellte Ziel ist ungültig. | Der Schlüsselname des geordneten Datenspeichers überschreitet das Limit von 50 Zeichen. |
| InvalidUniverse | Das bereitgestellte Universum ist ungültig. | Keine übereinstimmende Platz-ID für das Universum. Versuchen Sie es später erneut. |
| InvalidUserIds | Die bereitgestellten Benutzer-IDs haben ein ungültiges Format. | Fehler beim Parsen der Benutzer-IDs. |
| KeyThrottled | Die Anfragerate überschreitet das zulässige Maximum für den Schlüssel. | Die Anfragerate überschreitet die maximal zulässige Anfragerate für einen einzelnen Schlüssel. |
| KeyNotFound | Der angeforderte Schlüssel existiert nicht. | Der Schlüssel existiert nicht. |
| N/A | Keine Seiten zum Weiterblättern. | Dieser Fehler tritt auf, wenn Sie Pages:AdvanceToNextPageAsync() auf der letzten Seite aufrufen. |
| StandardReadExperienceThrottled | Die Anfragerate für den Standardlesevorgang überschreitet das zulässige Maximum für die Erfahrung. | Eine Anfrage an GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), oder das Lesen von UpdateAsync() auf einem Standard-Datenspeicher hat das StandardRead-Erfahrungsratenlimit überschritten. |
| StandardWriteExperienceThrottled | Die Anfragerate für den Standard-Schreibvorgang überschreitet das zulässige Maximum für die Erfahrung. | Eine Anfrage an SetAsync(), IncrementAsync(), oder das Schreiben von UpdateAsync() auf einem Standard-Datenspeicher hat das StandardWrite-Erfahrungsratenlimit überschritten. |
| StandardListExperienceThrottled | Die Anfragerate für den Standardlistenvorgang überschreitet das zulässige Maximum für die Erfahrung. | Eine Anfrage an ListKeysAsync(), ListVersionsAsync(), oder ListDataStoresAsync() auf Standard-Datenspeichern hat das StandardList-Erfahrungsratenlimit überschritten. |
| StandardRemoveExperienceThrottled | Die Anfragerate für den Standardentfernungsvorgang überschreitet das zulässige Maximum für die Erfahrung. | Eine Anfrage an RemoveAsync() auf einem Standard-Datenspeicher hat das StandardRemove-Erfahrungsratenlimit überschritten. |
| OrderedReadExperienceThrottled | Die Anfragerate für den geordneten Lesevorgang überschreitet das zulässige Maximum für die Erfahrung. | Eine Anfrage an GetAsync(), BatchGetAsync(), oder das Lesen von UpdateAsync() auf einem geordneten Datenspeicher hat das OrderedRead-Erfahrungsratenlimit überschritten. |
| OrderedWriteExperienceThrottled | Die Anfragerate für den geordneten Schreibvorgang überschreitet das zulässige Maximum für die Erfahrung. | Eine Anfrage an SetAsync(), IncrementAsync(), oder das Schreiben von UpdateAsync() auf einem geordneten Datenspeicher hat das OrderedWrite-Erfahrungsratenlimit überschritten. |
| OrderedListExperienceThrottled | Die Anfragerate für den geordneten Listenvorgang überschreitet das zulässige Maximum für die Erfahrung. | Eine Anfrage an GetSortedAsync() auf einem geordneten Datenspeicher hat das OrderedList-Erfahrungsratenlimit überschritten. |
| OrderedRemoveExperienceThrottled | Die Anfragerate für den geordneten Entfernenvorgang überschreitet das zulässige Maximum für die Erfahrung. | Eine Anfrage an RemoveAsync() auf einem geordneten Datenspeicher hat das OrderedRemove-Erfahrungsratenlimit überschritten. |
Limits
Datenmodelle haben Limits. Wenn eine Erfahrung diese Limits überschreitet, drosselt der Dienst automatisch die Nutzung des Datenspeichers der Erfahrung und verursacht, dass zukünftige Anfragen in eine der folgenden Warteschlangen gestellt werden:
- Setzen
- Geordnetes Setzen
- Holen
- Geordnetes Holen
Anfragen in einer Warteschlange werden in der Reihenfolge bearbeitet, in der sie empfangen wurden. Die aufgerufene Funktion gibt weiterhin nach, solange ihre Anfrage noch in der Warteschlange ist. Wenn der Datenspeicherschlüssel selbst gedrosselt wird, wird die Anfrage in eine Warteschlange gestellt, aber vorübergehend übersprungen.
Jede Warteschlange hat ein Limit von 30 Anfragen. Wenn das Limit einer Warteschlange erreicht ist, schlagen Anfragen mit einem Fehlercode im Bereich von 301-306 fehl, was darauf hinweist, dass die Anfragen vollständig abgelehnt wurden.
Zugriffslimits
Datenspeicher unterliegen sowohl Erfahrungs- als auch serverseitigen Limits. Die Limits auf Erfahrungsebene skalieren mit der Gesamtzahl der gleichzeitigen Benutzer in der Erfahrung, während die serverseitigen Limits konfigurierbar sind und als Werkzeug vom Ersteller verwendet werden sollen.
Erfahrungsgrenzen
Jede Erfahrung darf eine bestimmte Anzahl von Datenspeicheranfragen basierend auf dem Datenspeichertyp, dem Anfragetyp und der Anzahl der gleichzeitigen Benutzer haben. Für jeden Datenspeichertyp und Anfragetyp wird das Limit unter allen aufgeführten Funktionen geteilt.
- UpdateAsync() verbraucht sowohl das Lese- als auch das Schreibbudget. Ein einzelner Aufruf verringert beide Limits.
- Spieleserver und Open Cloud teilen ein Budget; Open Cloud-Verkehr kann durch die Nutzung innerhalb der Erfahrung gedrosselt werden (und umgekehrt). Siehe Kontrollieren Sie die Ratenlimits für weitere Hinweise.
Standard-Datenspeicher
| Anfragetyp | Spieleserver-API | Open Cloud-API | Geteilte Limits (Anfragen pro Minute) |
|---|---|---|---|
| Lesen | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() UpdateAsync() | Datenspeichereintrag abrufen | 300 + gleichzeitigeBenutzer × 40 |
| Schreiben | SetAsync() IncrementAsync() UpdateAsync() | Datenspeichereintrag erstellen, aktualisieren, erhöhen | 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
| Anfragetyp | Spieleserver-API | Open Cloud-API | Geteilte Limits (Anfragen pro Minute) |
|---|---|---|---|
| Lesen | GetAsync() BatchGetAsync() UpdateAsync() | Geordneten Datenspeichereintrag abrufen | 300 + gleichzeitigeBenutzer × 40 |
| Schreiben | SetAsync() IncrementAsync() UpdateAsync() | Geordneten Datenspeichereintrag erstellen, aktualisieren, erhöhen | 300 + gleichzeitigeBenutzer × 20 |
| Auflisten | GetSortedAsync() | Geordnete Datenspeichereinträge auflisten | 300 + gleichzeitigeBenutzer × 2 |
| Entfernen | RemoveAsync() | Geordneten Datenspeichereintrag löschen | 300 + gleichzeitigeBenutzer × 40 |
Kontrollieren Sie die Ratenlimits
Da Open Cloud- und Spieleserveranfragen geteilt werden, ist es wichtig, unabhängig zu steuern, wie viel jeder aus dem Budget verbrauchen kann.
Spieleserver
Einzelne Server haben eingebaute Limits, wie oben beschrieben. Verwenden Sie eine Kombination aus SetRateLimitForRequestType() und GetRequestBudgetForRequestType(), um eine feinkörnige Kontrolle über den Beitrag einzelner Server zum Gesamtbudget aufrechtzuerhalten.
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 Wartezeit hinzu, insbesondere wenn Sie dieselbe API in einer kontinuierlichen Schleife aufrufen. Setzen Sie diese Wartezeit auf 60 / (gewünschter Budgetverbrauch pro Minute) Sekunden als obere Grenze. Beachten Sie, dass dieser Ansatz keine Anfragen in Stößen 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/';
// --- Ratenbegrenzung pro Operation (Anfragen pro Minute) ---
const LIST_RATE_PER_MIN = 60;
const GET_RATE_PER_MIN = 120;
const UPDATE_RATE_PER_MIN = 60;
// Obergrenze für den Abstand 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 den eigenen Intervall dieser Operation, bevor sie zurückgegeben wird.
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 eine Zeichenfolge 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('Ein Fehler ist während der Ausführung aufgetreten:', error);
}
})();Serverlimits
Jeder Server hat ein konfigurierbares Ratenlimit für jeden Anfragetyp, basierend auf der Anzahl der Spieler in diesem Server. Server erhalten einen einmaligen Start-Burst von zusätzlichem Anfragebudget, wenn sie zum ersten Mal erstellt werden. Verwenden Sie GetRequestBudgetForRequestType(), um die Anzahl der Datenspeicheranfragen zu bestätigen, die der aktuelle Server zu einem bestimmten Zeitpunkt stellen kann.
Diese Limits sind konfigurierbar durch den Ersteller mithilfe der SetRateLimitForRequestType()-API. Mit dieser API kann ein Ersteller seine eigenen Ratenlimits für Datenspeicher für jeden Anfragetyp konfigurieren.
Die folgenden Standard-Ratenlimits gelten, wenn die API nicht aufgerufen wird:
Standard-Datenspeicher
| Anfragetyp | DataStoreRequestType Enum | Spieleserver-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
| Anfragetyp | DataStoreRequestType Enum | Spieleserver-API | Anfragen pro Minute |
|---|---|---|---|
| Lesen | OrderedRead | GetAsync() BatchGetAsync() 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 Bereich müssen alle eine bestimmte Zeichenlänge unterschreiten. Verwenden Sie string.len(), um ihre Länge zu überprüfen.
Die Daten (Schlüsselwert) werden ebenfalls als Zeichenfolge 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 |
| Bereich | 50 |
| Daten (Schlüsselwert) | 4.194.304 pro Schlüssel |
Metadatenlimits
Limits für die Anzahl der Zeichen in benutzerdefinierten Metadaten.
| Komponente | Maximale Anzahl von Zeichen |
|---|---|
| Schlüsselname | 50 |
| Wert | 250 |
| Schlüssel-Wert-Paare | 300 |
Durchsatzlimits
Durchsatzlimits pro Schlüssel 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 wird im Laufe der Zeit zurückgesetzt.
Roblox untersucht die Nutzung des mit dem Schlüssel verbundenen Kontingents in den 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.
| Anfragetyp | Spieleserver-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 von Datenspeichereinträgen | 4 MB pro Minute |
Zusätzlich zu 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 einer weiteren 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 Standard-Datenspeicher.
Speicherlimits
Um den Speicher stabil und skalierbar zu halten, verwenden Datenspeicher ein spielübergreifendes Limit für Ihre Speichernutzung.
Dieses Limit besteht aus einer Basiszuweisung für jedes Spiel plus einer zusätzlichen Zuweisung basierend auf der Anzahl der Lebenszeitbenutzer. Ein Lebenszeitbenutzer 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 × Anzahl der Lebenszeitbenutzer.
Die Speichernutzung wird anhand der komprimierten Größe der neuesten Version jedes Schlüssels gemessen. Datenspeicher komprimieren Ihre Daten automatisch vor der Speicherung, daher sollten Sie vermeiden, sie selbst vorab zu komprimieren. Die Vorabkomprimierung fügt unnötige CPU-Überlastung hinzu und kann die Effektivität der integrierten Komprimierung von Datenspeichern verringern. Durch die Speicherung unkomprimierter Daten profitieren Sie automatisch von Verbesserungen der Komprimierungsalgorithmen 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-Methode DeleteDataStore gelöscht wurden, zählen jedoch weiterhin während ihrer 30-tägigen Löschverarbeitungsperiode zu Ihrer Speichernutzung, bis sie dauerhaft entfernt werden.