記憶體儲存

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

MemoryStoreService 是一個高吞吐量和低延遲數據服務,可從活動會作業中的所有服務器快速存取內存數據。 記憶體儲存 適合快速變更且不需要持久的頻繁和短暫數據,因為它們的存取速度更快,且到達最長壽命時會消失。對於需要在會話之間持續的資料,請使用 資料儲存

數據結構

而不是直接存取原始資料,記憶體儲存有三種原始資料結構在服務器間共享快速處理:排序地圖隊列哈希地圖。每個數據結構都適合某些使用案例:

  • 技能基礎匹配 - 將用戶信息,例如技能等級,保存在服務器間的共用 隊列 中,並使用大廳服務器定期運行匹配。
  • 跨服務器交易和拍賣 - 啟用用戶可以在實時變更價格的物品進行投標的通用交易,並使用排序的鑰匙值對組合的地圖進行拍賣。
  • 全球排行榜 - 在排序地圖內的共用排行榜中儲存和更新用戶排名。
  • 共享庫存 - 將庫存項目和統計資料儲存在共用的 哈希地圖 中,用戶可以並行使用庫存項目。
  • 對永久數據進行緩存 - 將永久數據同步到資料儲存庫中的記憶儲存庫進行緩存 哈希地圖 ,以便提高體驗的履約。

一般來說,如果您需要根據特定鍵存取資料,請使用哈希地圖。如果需要將這些數據訂購,請使用排序的地圖。如果您需要按特定順序處理數據,請使用隊列。

限制和配額

為了維持可擴展性和系統性履約,記憶儲存有記憶大小、API 請求和資料結構尺寸的數據使用額度。

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

記憶體大小限制

記憶配額限制體驗可以使用的記憶總量。它不是固定值。相反,它會隨著時間變化,取決於體驗中的使用者數量,以下列方式計算: 64KB + 1KB * [使用者數量] 。額度適用於體驗等級,而不是服務器等級。

當使用者加入體驗時,額外的記憶容量即時可用。當使用者離開體驗時,額度不會立即減少。在額度重新評估為更低值之前,有一個追溯期為八天。

體驗使用記憶體大小上限後,任何增加記憶體大小的 API 請求都會失敗。要求減少或不更改記憶體大小仍然成功。

使用 可觀察 面板,您可以使用 記憶使用 圖表在實時查看體驗的記憶大小配額。

API 請求限制

對於 API 請求限制,有一個 請求單位 額度適用於所有 MemoryStoreService。配額是 1000 + 100 * [並行使用者數量] 每分鐘的請求單位。

大多數 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 回應狀態代碼的 狀態請求數量API x 狀態請求 圖表。要了解有關如何解決這些錯誤的更多信息,請參閱排除故障。對於錯誤相關的特定配額或限制,請參閱 限制和配額

狀態碼說明
成功成功。
數據結構記憶超出限制超出數據結構等級記憶體限制(100MB)。
資料更新衝突由於並行更新造成衝突。
存取遭拒未獲得存取經驗數據的權限。此請求不會消耗請求單位或使用額度。
內部錯誤內部錯誤。
無效請求請求沒有所需資訊或具有不正確的資訊。
數據結構項目超出限制超出數據結構等級項目數限制(1M)。
找不到物品在 或 中找不到項目。每 2 秒進行投票,直到找到隊列中的項目為止,返回此狀態代碼。
數據結構請求超出限制超出數據結構等級請求單限(每分鐘 100,000 請求單位)。
分割請求超出限制超出分割請求單位限制。
總請求超出限制超出宇宙級請求單位限制。
總記憶超出限制超出宇宙級記憶容量。
項目價值尺寸過大價值大小超出限制(32KB)。

下表列出從客戶端的狀態代碼,目前在可觀察性面板上無法使用。

狀態碼說明
內部錯誤內部錯誤。
未發布的地點您必須發布此位置才能使用 MemoryStoreService。
無效客戶端存取MemoryStoreService必須從伺服器呼叫。
無效的過期時間「過期」欄位的時間必須介於 0 和 3,888,000 之間。
無效請求無法將值轉換為 json。
無效請求無法將 sortKey 轉換為有效的數字或字串。
轉換呼叫失敗無法呼叫變換回呼函數。
請求限制最近的記憶儲存請求超過了一個或多個限制。
更新衝突超出最大重試次數。

排除問題

下表列出並說明每個回應狀態代碼的建議解決方案:

錯誤故障排除選項
數據結構請求超出限制/分區請求超出限制
  • 儲存資訊到另一個變量並在特定時間間隔後重新檢查本地緩存,例如 30 秒。:
  • 使用 按狀態請求數量 圖表來驗證您正在接收更多的 成功 回應,而不是 NoItemFounds 。限制你使用失敗請求擊中 MemoryStoreService 的次數。:
  • 實現請求之間的短延遲。:
  • 遵循 最佳實踐,包括:
    • 分割您的數據結構,如果您收到大量的 數據結構請求超出限制 / 分割請求超出限制 回應。:
    • 實裝指數退出以找到合理的請求傳送速率。
總請求超出限制
數據結構項目超出限制
數據結構記憶超出限制
總記憶超出限制
資料更新衝突
  • 實裝短延遲之間的請求,以避免多個請求同時更新相同的鑰匙。:
  • 對於排序的地圖,使用 方法上的回呼功能,在一定數量的嘗試後取消請求,如下代碼示例所示:
  • Example of Aborting Request

    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")
  • 調查以確認你是否有效地呼叫 MemoryStoreService 以避免衝突。理想情況下,你不應該過度傳送請求。:
  • 一次使用 方法為隊列和 方法為排序的地圖刪除項目。
內部錯誤
無效請求
  • 請確保您在請邀請中包含正確且有效的參數。無效參數的範例包括::
    • 空字串
    • 超出長度限制的字串
項目價值尺寸過大
  • 將物品值碎片或分割為多個鑰匙。
    • 為了組織分類的鑰匙,將鑰鍵添加 prefix 以字母順序排序。
  • 編碼或壓縮已儲存的值。

在工作室測試和調試

MemoryStoreService 中的數據被隔離在 Studio 和生產之間,因此在 Studio 中變更數據不會影響生產行為。這意味著來自 Studio 的 API 呼叫無法存取生產資料,因此您可以安全地在生產前測試記憶存儲和新功能。

工作室測試具有與生產相同的 限制和配額。對於基於使用者數量計算的額度,結果額度可能很小,因為你是唯一的使用者進行 Studio 測試。當從工作室測試時,您也可能會注意到稍微高於使用在生產中的延遲和錯誤率,是因為進行驗證存取和權限的一些額外檢查。

要了解如何在實時體驗或在工作室測試時偵錯記憶儲存的方法,請使用 開發者控制台