記憶體儲存

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

MemoryStoreService 是一個高吞吐量和低延遲的資料服務,提供可從所有伺服器訪問的快速記憶體儲存。在所有活動會話中,記憶體儲存 適合於頻繁且瞬息萬變的資料,這些資料不需要持久性,因為它們的存取速度更快,並且在達到最大生命週期時會消失。對於需要在會話之間持久化的資料,請使用 資料儲存

資料結構

記憶體儲存不直接訪問原始資料,而是有三種在伺服器之間共享的原始資料結構,以便快速處理:排序映射佇列雜湊映射。每種資料結構都適合某些特定的用例:

  • 技能匹配 - 在伺服器之間使用共享 佇列 保存用戶信息,如技能等級,並使用大廳伺服器定期運行匹配。
  • 伺服器之間交易和拍賣 - 在不同伺服器之間啟用普遍交易,使用具有實時變化價格的鍵值對的 排序映射 來出價。
  • 全球排行榜 - 在共享的 排序映射 中存儲和更新用戶排名。
  • 共享物品清單 - 在共享的 雜湊映射 中保存物品及統計資料,用戶可以同時使用彼此的物品。
  • 持久資料的快取 - 將您的持久資料在資料儲存中同步並複製到記憶體儲存 雜湊映射 中,該映射可作為快取並改善您的遊戲性能。

一般來說,如果您需要根據特定鍵訪問資料,請使用雜湊映射。如果您需要資料按順序排列,請使用排序映射。如果您需要以特定順序處理資料,請使用佇列。

限制與配額

為了維持可擴展性和系統性能,記憶體儲存對記憶體大小、API 請求和資料結構大小設有限制。

記憶體儲存有基於過期時間的驅逐政策,也稱為生命週期 (TTL)。項目在過期後被驅逐,之後記憶體配額會釋放出來以容納新條目。當您達到記憶體限制時,所有後續的寫入請求會失敗,直到項目過期或您手動刪除它們。

記憶體大小配額

記憶體配額限制了一個遊戲可以消耗的記憶體總量。這不是固定值,而是根據遊戲中的用戶數量隨時間變化,根據公式 64KB + 1.2KB * [用戶數量] 計算。該配額是在遊戲層級上應用,而不是伺服器層級。

當用戶加入遊戲時,額外的記憶體配額會立即可用。當用戶離開遊戲時,配額不會立即減少。在配額重新評估為較低值之前,會有八天的追溯期。

當您的遊戲達到記憶體大小限制時,任何增加記憶體大小的 API 請求都會失敗。減少或不變更記憶體大小的請求仍會成功。

透過 可觀察性 儀表板,您可以實時查看遊戲的記憶體大小配額,使用 記憶體使用情況 圖表。

API 請求限制

所有 MemoryStoreService API 調用將應用 請求單元 配額,每分鐘 1000 + 120 * [同時用戶數] 的請求單位。

大多數 API 調用只消耗一個請求單元,只有少數例外:

請求配額同樣適用於遊戲層級,而不是伺服器層級。這提供了靈活性,只要總請求速率不超過配額,就可以在伺服器之間分配請求。如果您超過了配額,服務將限流,並在請求時返回錯誤響應。

通過可用的 可觀察性 功能,您可以實時查看遊戲的請求單位配額。

資料結構大小限制

對於單個排序映射或佇列,適用以下大小和項目數限制:

  • 最大項目數:1,000,000
  • 最大總大小(包括排序映射的鍵):100 MB

每分區限制

請參見 每分區限制

最佳實踐

為了保持記憶體使用模式最佳,並避免觸發 限制,請遵循以下最佳實踐:

  • 刪除已處理的項目。 持續使用 MemoryStoreQueue:RemoveAsync() 方法清理佇列的讀取項目,並使用 MemoryStoreSortedMap:RemoveAsync() 清理排序映射,可以釋放記憶體並保持資料結構的最新。

  • 在添加資料時將過期時間設置為可能的最短時間。 雖然 MemoryStoreQueue:AddAsync()MemoryStoreSortedMap:SetAsync() 的默認過期時間均為 45 天,但設置最短時間可以自動清理舊資料,以防止它們填滿您的記憶體使用配額。

    • 不要存儲大量資料及長時間過期,因為這風險超過您的記憶體配額,並可能導致問題破壞整個遊戲。
    • 始終要明確刪除不需要的項目,或設置短期項目過期時間。
    • 通常,您應使用明確刪除來釋放記憶體,而使用項目過期作為安全機制,以防未使用的項目長時間佔據記憶體。
  • 僅在記憶體中保留必要的值。

    例如,對於拍賣行遊戲,您只需維護最高出價。您可以在一個鍵上使用 MemoryStoreSortedMap:UpdateAsync() 來保持最高出價,而不是在資料結構中保留所有出價。

  • 使用 指數退避 來幫助保持在 API 請求限制之下。

    例如,如果您收到 DataUpdateConflict,可以在兩秒後重試,然後是四秒、八秒等,而不是持續向 MemoryStoreService 發送請求以獲得正確的回應。

  • 通過 分片 將巨大的資料結構拆分為多個較小的結構。

    通常,在較小的結構中管理資料更容易,而不是將所有內容存儲在一個大型資料結構中。這種方法也有助於避免使用和速率限制。例如,如果您有一個使用前綴作為鍵的排序映射,考慮將每個前綴分開為自己的排序映射。對於特別受歡迎的遊戲,您甚至可以根據用戶 ID 的最後幾位數字將用戶分成多個映射。

  • 分片 在雜湊映射中經常訪問的鍵,使用多個相同的鍵以分散負載。

  • 壓縮儲存的值。

    例如,考慮使用 LZW 算法來減小儲存值的大小。

  • 註冊擴展服務。

    您可以通過註冊 擴展服務 來增加儲存和請求限制配額。

可觀察性

可觀察性儀表板 提供有關監控和故障排除記憶體儲存使用情況的見解和分析。通過實時更新不同方面的記憶體使用和 API 請求的圖表,您可以跟踪遊戲的記憶體使用模式,查看當前已分配的配額,監控 API 狀態,並識別潛在的性能優化問題。

以下表格列出了所有可在可觀察性儀表板的 根據狀態的請求數量根據 API x 狀態的請求 圖表中找到的 API 響應的狀態碼及描述。如需了解如何解決這些錯誤的更多信息,請參見 故障排除。有關錯誤所涉及的具體配額或限制,請參見 限制與配額

狀態碼描述
成功成功。
DataStructureMemoryOverLimit超過資料結構層級記憶體大小限制 (100MB)。
DataUpdateConflict由於同時更新而產生衝突。
AccessDenied未經授權訪問遊戲資料。該請求不消耗請求單位或使用配額。
InternalError內部錯誤。
InvalidRequest請求沒有所需的信息或信息格式錯誤。
DataStructureItemsOverLimit超過資料結構層級項目數限制 (1M)。
NoItemFoundMemoryStoreQueue:ReadAsync()MemoryStoreSortedMap:UpdateAsync() 中未找到項目。ReadAsync() 每 2 秒輪詢一次,直到找到佇列中的項目為止,則返回此狀態碼。
DataStructureRequestsOverLimit超過資料結構層級請求單位限制 (每分鐘 100,000 請求單位)。
PartitionRequestsOverLimit超過分區請求單位限制。
TotalRequestsOverLimit超過宇宙級請求單位限制。
TotalMemoryOverLimit超過宇宙級記憶體配額。
ItemValueSizeTooLarge值大小超過限制 (32KB)。

以下表格列出了來自客戶端的狀態碼,這些狀態碼目前在可觀察性儀表板上不可用。

狀態碼描述
InternalError內部錯誤。
UnpublishedPlace您必須發佈此地點以使用 MemoryStoreService。
InvalidClientAccessMemoryStoreService 必須從伺服器調用。
InvalidExpirationTime欄位 'expiration' 時間必須在 0 和 3,888,000 之間。
InvalidRequest無法將值轉換為 json。
InvalidRequest無法將 sortKey 轉換為有效的數字或字符串。
TransformCallbackFailed無法調用轉換回調函數。
RequestThrottled最近的 MemoryStores 請求達到一個或多個限制。
UpdateConflict超過最大重試次數。

故障排除

以下表格列出了每個響應狀態碼的建議解決方案:

錯誤故障排除選項
DataStructureRequestsOverLimit / PartitionRequestsOverLimit
  • 通過將信息保存到另一個變量並在一定時間間隔(例如 30 秒)後重新檢查來添加本地快取。
  • 使用 根據狀態的請求數量 圖表核實您收到的 成功 響應是否多於 未找到項目。限制您因請求失敗而進入 MemoryStoreService 的次數。
  • 在請求之間實施短暫的延遲。
  • 遵循 最佳實踐,包括:
    • 如果收到大量 DataStructureRequestsOverLimit/PartitionRequestsOverLimit 響應,則對資料結構進行分片。
    • 如果在雜湊映射調用中接收到大量 PartitionRequestsOverLimit 響應,則對其鍵進行分片。
    • 如果您看到 PartitionRequestsOverLimit 響應,則減少或批量處理對特定資料結構或雜湊映射鍵的調用。
    • 實施指數退避,以尋找合理的請求速率。
TotalRequestsOverLimit
DataStructureItemsOverLimit
DataStructureMemoryOverLimit
TotalMemoryOverLimit
DataUpdateConflict
  • 在請求之間實施短暫的延遲,以避免多個請求同時更新同一鍵。
  • 對於排序映射,在 MemoryStoreSortedMap:UpdateAsync() 方法上使用回調函數,在一定次數的嘗試後放棄請求,如以下示例代碼所示:
  • 中止請求的示例

    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.highestBid)
    return nil
    end, 1000)
    end
    placeBid("MyItem", 50)
    placeBid("MyItem", 40)
    print("完成")
  • 調查您是否有效地調用 MemoryStoreService 以避免衝突。理想情況下,您不應過度發送請求。
  • 一經讀取,立即使用 MemoryStoreQueue:RemoveAsync() 方法清除佇列的項目,並使用 MemoryStoreSortedMap:RemoveAsync() 方法清除排序映射項目。
內部錯誤
InvalidRequest
  • 確保在請求中包含正確且有效的參數。無效參數的示例包括:
    • 空字符串
    • 超過長度限制的字符串
ItemValueSizeTooLarge
  • 將項目值分片或拆分為多個鍵。
    • 為了組織分組鍵,通過向鍵添加 prefix 使其按字母順序排序。
  • 編碼或壓縮儲存的值。

在 Studio 測試和除錯

MemoryStoreService 中的資料在 Studio 和生產環境之間是隔離的,因此在 Studio 中更改資料不會影響生產行為。這意味著您在 Studio 的 API 調用不會訪問生產資料,允許您安全地測試記憶體儲存和新功能,然後再進入生產環境。

Studio 測試具有與生產相同的 限制與配額。對於根據用戶數計算的配額,結果可能非常小,因為您是唯一的 Studio 測試用戶。當從 Studio 進行測試時,您可能還會注意到稍微較高的延遲,以及相較於生產環境使用情況,錯誤率的升高,這是由于為了驗證訪問和權限而進行的某些額外檢查。

有關如何在活動遊戲或在 Studio 測試時除錯記憶體儲存的資訊,請使用 開發者控制台

©2026 Roblox Corporation、Roblox、Roblox 標誌及 Powering Imagination 是我們在美國及其他國家地區的部分註冊與未註冊商標。