Praktik terbaik untuk penyimpanan memori

*Konten ini diterjemahkan menggunakan AI (Beta) dan mungkin mengandung kesalahan. Untuk melihat halaman ini dalam bahasa Inggris, klik di sini.

Gunakan praktik ini untuk mengatur data sementara, mendistribusikan beban, dan merespons masalah penyimpanan memori.

Tergantung pada jenis struktur data, MemoryStoreService memberlakukan batasan pada memori dan jumlah item dalam suatu struktur data. Semua struktur data juga dibatasi oleh batas permintaan global per-partisi.

Rancang kunci dan struktur data

Lihat Gunakan pola kunci statis dan awalan dalam Praktik terbaik untuk penyimpanan data. Terapkan pola tersebut pada kunci dan nama struktur data sehingga setiap server mengarahkan data logis yang sama ke lokasi yang sama.

Pilih waktu kedaluwarsa yang sesuai dengan berapa lama data tetap berguna. Jangan gunakan penyimpanan memori untuk catatan pemain yang persisten atau data yang harus bertahan setelah kedaluwarsa. Untuk bantuan memilih antara layanan, lihat Penyimpanan data versus penyimpanan memori.

Tangani kegagalan permintaan

Lihat Coba ulang kegagalan sementara dalam Praktik terbaik untuk penyimpanan data.

Utamakan UpdateAsync daripada SetAsync

Lihat Utamakan UpdateAsync daripada SetAsync dalam Praktik terbaik untuk penyimpanan data. Peta hash dan peta terurut menyediakan MemoryStoreHashMap:UpdateAsync() dan MemoryStoreSortedMap:UpdateAsync() untuk pola ini.

Jarakkan permintaan berulang

Lihat Jarakkan permintaan berulang dalam Praktik terbaik untuk penyimpanan data.

Pantau penggunaan

Gunakan Dasbor Observabilitas Penyimpanan Memori untuk memantau penggunaan kuota, volume permintaan, dan status respons. Tinjau peringatan email bawaan, konfigurasikan peringatan kustom untuk metrik penyimpanan memori yang penting, dan gunakan Laporan Kesalahan untuk menyelidiki kegagalan.

Kurangi permintaan, ukuran item, dan waktu kedaluwarsa sebelum meningkatkan kapasitas. Jika penggunaan yang sah melebihi kuota default, evaluasi Layanan Diperpanjang.

Kelola batas peta terurut dan antrean

Peta terurut dan antrean keduanya memiliki batasan pada jumlah item maksimum dan total memori maksimum. Selain itu, item dalam salah satu struktur data ini selalu berada di satu partisi. Setiap permintaan ke salah satu struktur data tersebut adalah permintaan ke partisi yang sama.

Ketika peta terurut atau antrean mencapai batas item atau memori, hapus item yang tidak perlu secara manual atau dengan menambahkan kebijakan kedaluwarsa. Jika hanya batas memori yang menyebabkan throttling, kurangi ukuran item dengan menghapus informasi yang tidak perlu dari kunci dan nilai.

Jika Anda memerlukan semua item Anda atau mengalami throttling karena throughput permintaan, satu-satunya solusi adalah sharding.

Distribusikan beban dengan sharding

Sharding adalah proses menyimpan sekumpulan data terkait di beberapa struktur data. Dengan kata lain, ini berarti mengambil struktur data dengan throughput tinggi yang ada dan menggantinya dengan beberapa yang lebih kecil yang bersama-sama berisi set data yang sama seperti yang asli.

Tantangan utama dalam sharding adalah menemukan cara untuk menyebarkan data di beberapa struktur data dengan cara yang mempertahankan fungsionalitas yang sama seperti yang asli.

Meskipun Roblox sudah mempartisi peta hash, Anda dapat lebih lanjut melakukan sharding dengan menyebarkan permintaan di antara beberapa kunci.

Sharding peta terurut

Untuk melakukan sharding catatan pemain dalam peta terurut, gunakan aritmatika modulo untuk menetapkan setiap Id ke salah satu dari sejumlah peta tetap. Contoh berikut menggunakan empat peta dan secara konsisten mengarahkan pengguna yang sama ke peta yang sama:

Sharding Peta Terurut
-- Inisialisasi Layanan Penyimpanan Memori
local MemoryStoreService = game:GetService("MemoryStoreService")
-- Buat ember Peta Terurut Anda
local sm1 = MemoryStoreService:GetSortedMap("sm1")
local sm2 = MemoryStoreService:GetSortedMap("sm2")
local sm3 = MemoryStoreService:GetSortedMap("sm3")
local sm4 = MemoryStoreService:GetSortedMap("sm4")
local sortedMaps = { sm1, sm2, sm3, sm4 }
-- Fungsi pembantu untuk mengambil ember yang benar dari Kunci Item
local function getSortedMapBucket(userId)
local bucketIndex = (userId % #sortedMaps) + 1
return sortedMaps[bucketIndex]
end
-- Inisialisasi pemain dengan nilai default 0
for _, player in game:GetService("Players"):GetPlayers() do
local userId = player.User.Id
local bucket = getSortedMapBucket(userId)
bucket:SetAsync(tostring(userId), 0, 600)
end
-- Ambil nilai pemain
local player = game:GetService("Players"):GetPlayers()[1]
local userId = player.User.Id
local bucket = getSortedMapBucket(userId)
local playerScore = bucket:GetAsync(tostring(userId))
print(playerScore)

Sharding antrean

Sharding antrean lebih rumit daripada sharding peta terurut. Meskipun Anda ingin menyebarkan throughput permintaan di beberapa antrean, penambahan, pembacaan, dan penghapusan hanya terjadi di depan atau belakang antrean.

Salah satu solusinya adalah menggunakan antrean berputar, yang berarti membuat beberapa antrean dan berputar di antara mereka saat Anda menambahkan atau membaca item:

  1. Buat beberapa antrean dan tambahkan ke dalam array.
  2. Buat dua penunjuk lokal. Satu mewakili antrean yang ingin Anda baca dan hapus itemnya. Yang lainnya mewakili antrean yang ingin Anda tambahkan item:
    • Untuk operasi baca, hitung jumlah item yang Anda butuhkan dari setiap antrean, serta di mana memindahkan penunjuk baca.
    • Untuk operasi hapus, kirim ID dari baca ke setiap antrean.
    • Untuk operasi tambah, tambahkan ke antrean di penunjuk tambah dan tingkatkan penunjuk.
Sharding Antrean
-- Inisialisasi Layanan Penyimpanan Memori
local MemoryStoreService = game:GetService("MemoryStoreService")
-- Buat Antrean Anda
local q1 = MemoryStoreService:GetQueue("q1")
local q2 = MemoryStoreService:GetQueue("q2")
local q3 = MemoryStoreService:GetQueue("q3")
local q4 = MemoryStoreService:GetQueue("q4")
-- Tempatkan Antrean dalam Array
local queueArr = { q1, q2, q3, q4 }
-- Buat dua penunjuk yang mewakili indeks antrean baca dan tambah
local readIndex = 1
local addIndex = 1
-- Buat fungsi lokal yang memperbarui indeks dengan tepat
local function rotateIndex(index, n)
return (index + n - 1) % 4 + 1
end
-- Buat fungsi lokal yang membaca n item dari antrean
local function readFromQueue(count, allOrNothing, waitTimeout)
local endIndex = count % 4
local countPerQueue = count // 4
local items = {}
local ids = {}
-- loop melalui setiap antrean
for i = 1, 4, 1 do
-- tentukan apakah antrean ini akan membaca item tambahan
local diff = i - readIndex
if diff < 0 then
diff += 4
end
local queue = queueArr[i]
-- baca item dari setiap antrean
-- +1 item jika memenuhi kriteria baca tambahan
if diff < endIndex then
items[i], ids[i] = queue:ReadAsync(countPerQueue + 1, allOrNothing, waitTimeout)
else
items[i], ids[i] = queue:ReadAsync(countPerQueue, allOrNothing, waitTimeout)
end
end
readIndex = rotateIndex(readIndex, count)
return items, ids
end
-- Buat fungsi lokal yang menghapus n item dari antrean
local function removeFromQueue(ids)
for i = 1, 4, 1 do
local queue = queueArr[i]
queue:RemoveAsync(ids[i])
end
end
-- Buat fungsi lokal yang menambahkan item ke antrean
local function addToQueue(itemKey, expiration, priority)
local queue = queueArr[addIndex]
queue:AddAsync(itemKey, expiration, priority)
addIndex = rotateIndex(addIndex, 1)
end
-- Tulis beberapa kode!
for _, player in game:GetService("Players"):GetPlayers() do
addToQueue(player.User.Id, 600, 0)
end
local players, ids = readFromQueue(20, true, -1)
removeFromQueue(ids)

Peta hash

Peta hash tidak memiliki batasan memori atau jumlah item individu dan secara otomatis di-shard, tetapi Anda masih dapat mengalami throttling jika menggunakannya dengan buruk.

Sebagai contoh, pertimbangkan sebuah permainan dengan peta hash data, disimpan sebagai nilai dari satu kunci bernama metadata. Jika metadata ini berisi objek bersarang dengan informasi seperti ID tempat, jumlah pemain, dan lainnya, setiap kali metadata diperlukan, Anda tidak punya pilihan selain memanggil GetAsync("metadata") dan mengambil seluruh objek. Dalam hal ini, semua permintaan pergi ke satu kunci dan oleh karena itu satu partisi.

Alih-alih menyimpan semua metadata sebagai satu objek bersarang, simpan setiap bidang yang diakses secara independen sebagai kunci tersendiri sehingga peta hash dapat memanfaatkan sharding otomatis. Jika Anda memerlukan pemisahan antara metadata dan sisa peta hash, tambahkan awalan penamaan, seperti metadata_user_count alih-alih user_count.

Jika satu atau beberapa kunci menerima permintaan yang sering, shard panggilan tersebut di antara beberapa kunci. Misalnya, jika semua server permainan mengambil nilai dari satu kunci peta hash, permintaan tersebut dapat menyebabkan throttling partisi. Untuk mengurangi beban, salin nilai ke beberapa kunci dan arahkan setiap server ke shard yang stabil.

©2026 Roblox Corporation. Roblox, logo Roblox, dan Powering Imagination termasuk dalam merek dagang kami yang terdaftar dan tidak terdaftar di AS dan negara lainnya.