数据存储错误代码和限制

*此内容使用人工智能(Beta)翻译,可能包含错误。若要查看英文页面,请点按 此处

您对数据存储的请求可能因为连接不良或其他问题而失败。为了处理错误并返回带有错误代码的消息,请将数据存储函数封装在 pcall() 中。

例如,UpdateAsync() 失败意味着游戏服务器没有收到成功的响应。这并不总是保证后台写入没有发生。在某些失败场景中,直到通过后续读取进行验证后,调用方可能不知道最终的写入状态。

错误代码参考

错误代码错误名称错误信息备注
101KeyNameEmpty键名不能为空。检查输入到数据存储函数中的键是否为空字符串。
102KeyNameLimit键名超过了 50 个字符的限制。检查输入到数据存储函数中的键是否超过 50 的长度。
103ValueNotAllowed不能在 DataStore 中允许X坏的更新函数返回了类型为X的值。
104CantStoreValue不能在 DataStore 中存储X更新函数返回的值为类型X,但未能序列化。
105ValueTooLarge序列化值超过了X的限制。如果您使用 SetAsync()UpdateAsync() 设置一个值,则该值的序列化长度不得超过X的大小。要检查数据的序列化长度,请使用 JSONEncode()
106MaxValueInvalidMaxValue 必须是一个整数。如果您为 GetSortedAsync() 传递最大值,则它必须是一个整数。
106MinValueInvalidMinValue 必须是一个整数。如果您为 GetSortedAsync() 传递最小值,则它必须是一个整数。
106PageSizeGreaterPageSize 必须在预定义范围内。OrderedDataStore 的最小页面大小为 1。
106PageSizeLesserPageSize 必须在预定义范围内。OrderedDataStore 的最大页面大小为 100。
107MinMaxOrderInvalidMaxValue 必须大于或等于 MinValue对于 GetSortedAsync(),最大值必须大于或等于最小值。
301GetAsyncThrottleGetAsync 请求被丢弃。请求被限制但队列已满。GetAsync() 请求超过了最大队列大小,Roblox无法以当前吞吐量处理请求。
302SetAsyncThrottleSetAsync 请求被丢弃。请求被限制但队列已满。SetAsync() 请求超过了最大队列大小,Roblox无法以当前吞吐量处理请求。
303IncreAsyncThrottleIncrementAsync 请求被丢弃。请求被限制但队列已满。IncrementAsync() 请求超过了最大队列大小,Roblox无法以当前吞吐量处理请求。
304UpdateAsyncThrottleUpdateAsync 请求被丢弃。请求被限制但队列已满。UpdateAsync() 请求超过了最大队列大小,Roblox无法以当前吞吐量处理请求。
304TransformThrottleUpdateAsync 请求被丢弃。请求被限制但队列已满。UpdateAsync() 请求超过了最大队列大小,Roblox无法以当前吞吐量处理请求。
305GetSortedThrottleGetSorted 请求被丢弃。请求被限制但队列已满。GetSortedAsync() 请求超过了最大队列大小,Roblox无法以当前吞吐量处理请求。
306RemoveAsyncThrottleRemoveAsync 请求被丢弃。请求被限制但队列已满。RemoveAsync() 请求超过了最大队列大小,Roblox无法以当前吞吐量处理请求。
401DataModelNoAccess请求失败。DataModel 在体验关闭时无法访问。DataModel 未初始化,因为体验正在关闭。
402LuaWebSrvsNoAccess请求失败。LuaWebService 在体验关闭时无法访问。LuaWebService 未初始化,因为体验正在关闭。
403StudioAccessToApisNotAllowed因为未启用 API 访问,无法从 Studio 写入 DataStore在 Studio 中使用数据存储之前,必须启用 API 访问。
404InternalErrorOrderedDataStore 不存在。与此请求相关的 OrderedDataStore 未找到。这可能是数据损坏的迹象。请稍后再试。
501InternalError无法解析响应,因为数据可能已损坏。服务器无法解析对您请求的响应。这可能是数据损坏的迹象。请稍后再试。
502RequestRejectedAPI 服务以错误 X 拒绝了请求。处理 Roblox 服务器时发生了错误 X。请稍后再试。
503InternalError数据存储请求成功,但未找到键。请求的键未在数据存储中找到。这可能是数据损坏的迹象。请稍后再试。
504InternalError数据存储请求成功,但响应格式不正确。服务器无法解析对您请求的响应。这可能是数据损坏的迹象。请稍后再试。
505InternalErrorOrderedDataStore 请求成功,但响应格式不正确。服务器无法解析对您的 OrderedDataStore 请求的响应。这可能是数据损坏的迹象。请稍后再试。
509OperationNotAllowed在个人 RCC 上运行时,数据存储操作被阻止,以防止可能的数据损坏。在私人 RCC 通道上,数据存储写入被阻止。
511AttributeSizeTooLarge元数据属性大小超过了X的限制。序列化的元数据大小超过了X的限制。值X是动态的。如果大小发生变化,值也会变化。
512UserIdLimitExceededUserID大小超过了X的限制。用户提供的用户 ID 数组的长度超过了X的限制。
513AttributeFormatError属性 userId 格式无效。提供的用户 ID 不是数字。
513AttributeFormatError属性元数据格式无效。元数据不是表。
GetVersionAsyncThrottleGetVersionAsync 请求被丢弃。请求已被限制。GetVersionAsync() 请求超过了最大队列大小,Roblox无法以当前吞吐量处理请求。
GetVersionAtTimeAsyncThrottleGetVersionAtTimeAsync 请求被丢弃。请求已被限制。GetVersionAtTimeAsync() 请求超过了最大队列大小,Roblox无法以当前吞吐量处理请求。
ListDataStoresAsyncThrottleListDataStoresAsync 请求被丢弃。请求已被限制。ListDataStoresAsync() 请求超过了最大队列大小,Roblox无法以当前吞吐量处理请求。
ListKeysAsyncThrottleListKeysAsync 请求被丢弃。请求已被限制。ListKeysAsync() 请求超过了最大队列大小,Roblox无法以当前吞吐量处理请求。
ListVersionsAsyncThrottleListVersionsAsync 请求被丢弃。请求已被限制。ListVersionsAsync() 请求超过了最大队列大小,Roblox无法以当前吞吐量处理请求。
RemoveVersionAsyncThrottleRemoveVersionAsync 请求被丢弃。请求已被限制。RemoveVersionAsync() 请求超过了最大队列大小,Roblox无法以当前吞吐量处理请求。
InvalidTimestamp时间戳必须是正数,且不超过未来十分钟。提供给 GetVersionAtTimeAsync() 的时间戳无效。
StandardReadExperienceThrottledStandardRead 请求被体验限制而限制。GetAsync()GetVersionAsync()GetVersionAtTimeAsync()或对标准数据存储上的 UpdateAsync() 的读取请求超过了 StandardRead 体验级限速。
StandardWriteExperienceThrottledStandardWrite 请求被体验限制而限制。SetAsync()IncrementAsync() 或对标准数据存储上的 UpdateAsync() 的写入请求超过了 StandardWrite 体验级限速。
StandardListExperienceThrottledStandardList 请求被体验限制而限制。ListKeysAsync()ListVersionsAsync() 或对标准数据存储上的 ListDataStoresAsync() 的请求超过了 StandardList 体验级限速。
StandardRemoveExperienceThrottledStandardRemove 请求被体验限制而限制。对标准数据存储上的 RemoveAsync() 的请求超过了 StandardRemove 体验级限速。
OrderedReadExperienceThrottledOrderedRead 请求被体验限制而限制。GetAsync() 或对有序数据存储上的 UpdateAsync() 的读取请求超过了 OrderedRead 体验级限速。
OrderedWriteExperienceThrottledOrderedWrite 请求被体验限制而限制。SetAsync()IncrementAsync() 或对有序数据存储上的 UpdateAsync() 的写入请求超过了 OrderedWrite 体验级限速。
OrderedListExperienceThrottledOrderedList 请求被体验限制而限制。对有序数据存储上的 GetSortedAsync() 请求超过了 OrderedList 体验级限速。
OrderedRemoveExperienceThrottledOrderedRemove 请求被体验限制而限制。对有序数据存储上的 RemoveAsync() 请求超过了 OrderedRemove 体验级限速。
StandardReadGameServerThrottledStandardRead 请求因游戏服务器限制或请求队列已满而受到限制。GetAsync()GetVersionAsync()GetVersionAtTimeAsync() 或对标准数据存储上的 UpdateAsync() 的读取请求超过了 StandardRead 游戏服务器级限速。
StandardWriteGameServerThrottledStandardWrite 请求因游戏服务器限制或请求队列已满而受到限制。SetAsync()IncrementAsync() 或对标准数据存储上的 UpdateAsync() 的写入请求超过了 StandardWrite 游戏服务器级限速。
StandardListGameServerThrottledStandardList 请求因游戏服务器限制或请求队列已满而受到限制。ListKeysAsync()ListVersionsAsync() 或对标准数据存储上的 ListDataStoresAsync() 的请求超过了 StandardList 游戏服务器级限速。
StandardRemoveGameServerThrottledStandardRemove 请求因游戏服务器限制或请求队列已满而受到限制。对标准数据存储上的 RemoveAsync() 请求超过了 StandardRemove 游戏服务器级限速。
OrderedReadGameServerThrottledOrderedRead 请求因游戏服务器限制或请求队列已满而受到限制。GetAsync() 或对有序数据存储上的 UpdateAsync() 的请求超过了 OrderedRead 游戏服务器级限速。
OrderedWriteGameServerThrottledOrderedWrite 请求因游戏服务器限制或请求队列已满而受到限制。SetAsync()IncrementAsync() 或对有序数据存储上的 UpdateAsync() 的请求超过了 OrderedWrite 游戏服务器级限速。
OrderedListGameServerThrottledOrderedList 请求因游戏服务器限制或请求队列已满而受到限制。对有序数据存储上的 GetSortedAsync() 请求超过了 OrderedList 游戏服务器级限速。
OrderedRemoveGameServerThrottledOrderedRemove 请求因游戏服务器限制或请求队列已满而受到限制。对有序数据存储上的 RemoveAsync() 请求超过了 OrderedRemove 游戏服务器级限速。

服务器错误代码

错误名称错误信息备注
DatastoreDeleted数据存储已被删除。无法在数据存储上执行操作,因为数据存储之前已被删除。
DatastoreThrottled请求速率超过了 datastore 允许的最大值。发送给单个数据存储的请求过多。
InternalServerError发生内部服务器错误。Roblox 服务器上偶然出现的错误。请重试,理想情况下使用指数退避。
InvalidExclusiveStartKey提供的排他性起始键无效。提供给列表操作(如 ListKeysAsync())的排他性起始键 (游标) 无效。
InvalidPlace提供的地点无效。该地点没有匹配的宇宙 ID。请稍后再试。
InvalidTarget提供的目标无效。有序数据存储的键名超过 50 个字符的限制。
InvalidUniverse提供的宇宙无效。该宇宙没有匹配的地点 ID。请稍后再试。
InvalidUserIds提供的用户 ID 格式无效。解析用户 ID 失败。
KeyThrottled请求速率超过了该键的最大允许值。请求速率超过了单个键的最大允许请求速率。
KeyNotFound请求的键不存在。该键不存在。
N/A没有页面可以继续。当您在最后一页上调用 Pages:AdvanceToNextPageAsync() 时会出现此错误。
StandardReadExperienceThrottled标准读取请求速率超过了体验允许的最大值。GetAsync()GetVersionAsync()GetVersionAtTimeAsync() 或标准数据存储上的 UpdateAsync() 的读取请求超过了 StandardRead 体验级限速。
StandardWriteExperienceThrottled标准写入请求速率超过了体验允许的最大值。SetAsync()IncrementAsync() 或标准数据存储上的 UpdateAsync() 的写入请求超过了 StandardWrite 体验级限速。
StandardListExperienceThrottled标准列表请求速率超过了体验允许的最大值。ListKeysAsync()ListVersionsAsync() 或标准数据存储上的 ListDataStoresAsync() 的请求超过了 StandardList 体验级限速。
StandardRemoveExperienceThrottled标准移除请求速率超过了体验允许的最大值。对标准数据存储上的 RemoveAsync() 的请求超过了 StandardRemove 体验级限速。
OrderedReadExperienceThrottled有序读取请求速率超过了体验允许的最大值。GetAsync() 或对有序数据存储上的 UpdateAsync() 的请求超过了 OrderedRead 体验级限速。
OrderedWriteExperienceThrottled有序写入请求速率超过了体验允许的最大值。SetAsync()IncrementAsync() 或对有序数据存储上的 UpdateAsync() 的请求超过了 OrderedWrite 体验级限速。
OrderedListExperienceThrottled有序列表请求速率超过了体验允许的最大值。对有序数据存储上的 GetSortedAsync() 请求超过了 OrderedList 体验级限速。
OrderedRemoveExperienceThrottled有序移除请求速率超过了体验允许的最大值。对有序数据存储上的 RemoveAsync() 请求超过了 OrderedRemove 体验级限速。

限制

数据模型有 限制。如果体验超过这些限制,服务会自动限制体验的数据存储使用,并导致未来的请求被放置在以下队列之一:

  • 设置
  • 有序设置
  • 获取
  • 有序获取

队列中的请求按照接收的顺序处理。调用的函数将继续让渡,只要其请求仍然排队。如果数据存储键本身被限制,请求仍会被放入队列,但将被暂时跳过。

每个队列的限制为 30 个请求。当队列限制达到时,请求将失败,并伴随 301-306 范围内的错误代码,表示请求已完全丢弃。

访问限制

数据存储受到 体验级和服务器级限制 的约束。体验级限制随着体验中并发用户的总数而变化,而服务器级限制是可配置的,旨在作为创建者的工具。

体验限制

每个体验根据数据存储类型、请求类型和并发用户数限制一定数量的数据存储请求。对于每种数据存储类型和请求类型,该限制是所有列出函数共享的。

  • UpdateAsync() 从读取和写入请求预算中消耗。这单次调用将同时减少两个限制。
  • 游戏服务器和开放云 共享 预算;开放云流量可以被体验内的使用所限制(反之亦然)。有关更多指导,请参见 控制速率限制
标准数据存储
请求类型游戏服务器 API开放云 API共享限制(每分钟请求数量)
读取GetAsync()
GetVersionAsync()
GetVersionAtTimeAsync()
UpdateAsync()
获取数据存储条目300 + 并发用户 × 40
写入SetAsync()
IncrementAsync()
UpdateAsync()
创建、更新、增量数据存储条目300 + 并发用户 × 20
列表ListDataStoresAsync()
ListKeysAsync()
ListVersionsAsync()
列出数据存储、列出数据存储条目、列出数据存储条目修订版300 + 并发用户 × 2
移除RemoveAsync()删除数据存储条目、删除数据存储、恢复删除数据存储300 + 并发用户 × 40
有序数据存储
请求类型游戏服务器 API开放云 API共享限制(每分钟请求数量)
读取GetAsync()
UpdateAsync()
获取有序数据存储条目300 + 并发用户 × 40
写入SetAsync()
IncrementAsync()
UpdateAsync()
创建、更新、增量有序数据存储条目300 + 并发用户 × 20
列表GetSortedAsync()列出有序数据存储条目300 + 并发用户 × 2
移除RemoveAsync()删除有序数据存储条目300 + 并发用户 × 40
控制速率限制

由于开放云和游戏服务器请求是共享的,因此独立控制每个请求可以消耗多少预算非常重要。

游戏服务器

每个服务器都有内置限制,如上所述。使用 SetRateLimitForRequestType()GetRequestBudgetForRequestType() 的组合来保持对单个服务器对总预算贡献的细粒度控制。

开放云

开放云请求需要外部速率限制解决方案。我们推荐以下一种方法:

  • (简单)在每个请求后添加短暂超时,特别是在连续循环调用相同 API 时。将此超时设置为 60 / (每分钟希望消耗的预算) 秒,作为上限。请注意,该方法不允许以突发形式发送请求。
  • (稳健)使用漏桶策略实现本地速率限制器。

以下 Node.js 代码示例包括参考实现。

const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error('The API_KEY environment variable is not set.');
}
const apiHeaderKey = 'x-api-key';
const universeId = '';
const dataStoreId = 'Inventory';
const baseUrl = 'https://apis.roblox.com/cloud/v2/';
// --- 每个操作的速率限制配置(每分钟请求数)---
const LIST_RATE_PER_MIN = 60;
const GET_RATE_PER_MIN = 120;
const UPDATE_RATE_PER_MIN = 60;
// 每个操作的上限间隔:60 / (每分钟请求数) 秒。
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));
// 执行请求,然后在返回之前等待该操作自己的间隔。
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) // 主体必须是字符串
}, 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(`\n处理条目: ${path}`);
const currentData = await getEntry(path);
currentData.value.currency += 10;
const payload = { value: currentData.value };
const updateResponse = await updateEntry(path, payload);
console.log(`状态: ${updateResponse.status}`);
console.log(`响应: ${await updateResponse.text()}`);
}
} catch (error) {
console.error('执行期间发生错误:', error);
}
})();

服务器限制

每个服务器都有为每种请求类型配置的速率限制,基于该服务器的玩家数量。服务器在首次创建时会获得一次性的额外请求预算。使用 GetRequestBudgetForRequestType() 确认当前服务器在任何给定时间可以发出的数据存储请求数量。

这些限制是 可由创建者配置的,使用 SetRateLimitForRequestType() API。通过此 API,创建者可以为每种请求类型配置自己的数据存储速率限制。

以下 默认速率限制 适用,如果没有调用 API:

标准数据存储
请求类型DataStoreRequestType 枚举游戏服务器 API每分钟请求数
读取StandardReadGetAsync()
GetVersionAsync()
GetVersionAtTimeAsync()
UpdateAsync()
60 + 玩家数量 × 40
写入StandardWriteSetAsync()
IncrementAsync()
UpdateAsync()
60 + 玩家数量 × 40
列表StandardListListDataStoresAsync()
ListKeysAsync()
ListVersionsAsync()
5 + 玩家数量 × 2
移除StandardRemoveRemoveAsync()60 + 玩家数量 × 40
移除版本(已弃用)RemoveVersionAsyncRemoveVersionAsync()5 + 玩家数量 × 2
有序数据存储
请求类型DataStoreRequestType 枚举游戏服务器 API每分钟请求数
读取OrderedReadGetAsync()
UpdateAsync()
60 + 玩家数量 × 40
写入OrderedWriteSetAsync()
IncrementAsync()
UpdateAsync()
30 + 玩家数量 × 5
列表OrderedListGetSortedAsync()5 + 玩家数量 × 2
移除OrderedRemoveRemoveAsync()30 + 玩家数量 × 5

数据限制

数据存储限制每个条目可以使用多少数据。

数据存储名、键名和 范围 都必须在一定的字符长度之下。使用 string.len() 检查它们的长度。

数据(键值)也作为字符串存储,无论其初始类型如何。您可以使用 JSONEncode() 函数检查数据的大小,该函数将 Luau 数据转换为一个序列化的 JSON 表。

组件最大字符数
数据存储名50
键名50
范围50
数据(键值)每个键 4,194,304

元数据限制

用户定义的元数据字符数量限制。

组件最大字符数
键名50
250
键值对300

吞吐量限制

每个键的吞吐量限制确保 Roblox 服务器的性能最佳。每个限制适用于体验中所有服务器中的每个键,并随时间刷新。

Roblox 会检查与键相关的配额使用情况,在过去的 60 秒内。如果使用情况(包括当前请求)在吞吐量限制之内,请求将被批准。如果使用情况超过限制,请求将被拒绝。

请求类型游戏服务器 API开放云 API限制
读取GetAsync()
GetVersionAsync()
GetVersionAtTimeAsync()
ListVersionsAsync()
UpdateAsync()
获取数据存储条目每分钟 25 MB
写入SetAsync()
IncrementAsync()
UpdateAsync()
RemoveAsync()
创建、更新、增量、移除数据存储条目每分钟 4 MB

除了上述吞吐量限制之外,Roblox 根据内部架构将数据组织为分区。因此,当后端服务器接收到对同一数据存储的高并发请求时,可能会导致进一步的限制。无论原因如何,限制表现为 DatastoreThrottledKeyThrottled 错误,具体取决于是对于单一数据存储超过了吞吐量限制还是对于某个键超过了。无论是有序数据存储还是标准数据存储,这些错误消息都适用。

存储限制

为了保持存储稳定和可扩展,数据存储在游戏级别使用存储使用限制。

该限制由每个游戏的基础分配加上基于终身用户数量的额外分配组成。终身用户是指至少加入过游戏一次的任何用户。

存储限制的计算公式为 总最新版本存储限制 = 500 MB + 每个终身用户 1 MB

存储使用量是通过每个键最新版本的 压缩大小 来衡量的。数据存储会在存储前自动压缩数据,因此请避免自行预压缩。预压缩会增加不必要的 CPU 开销,并可能降低数据存储的内置压缩效果。通过存储未压缩数据,您可以自动从 Roblox 压缩算法的改进和将来的基于架构的优化中受益。

只有每个键的最新版本计入您的存储使用量。已删除的键和被替代的版本,在其保留期内仍可通过版本 API 访问,但不会算作存储使用量。然而,通过开放云 DeleteDataStore 方法删除的数据存储在其 30 天删除处理期间仍计入存储使用量,直到永久删除。

©2026 Roblox Corporation、Roblox、Roblox 标志及 Powering Imagination 是我们在美国及其他国家或地区的注册与未注册商标。