Penyimpanan Memori

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

MemoryStoreService adalah layanan data dengan throughput tinggi dan latensi rendah yang menyediakan penyimpanan data dalam memori yang cepat dan dapat diakses dari semua server dalam sesi langsung. Penyimpanan Memori cocok untuk data yang sering dan sementara yang berubah dengan cepat dan tidak perlu tahan lama, karena lebih cepat diakses dan menghilang saat mencapai masa hidup maksimum. Untuk data yang perlu bertahan di antara sesi, gunakan data store.

Struktur data

Alih-alih mengakses data mentah secara langsung, penyimpanan memori memiliki tiga struktur data primitif yang dibagikan di seluruh server untuk pemrosesan cepat: peta terurut, antrian, dan peta hash. Setiap struktur data cocok untuk kasus penggunaan tertentu:

  • Pencocokan berbasis keterampilan - Simpan informasi pengguna, seperti tingkat keterampilan, dalam antrian bersama di antara server, dan gunakan server lobi untuk menjalankan pencocokan secara berkala.
  • Perdagangan dan lelang antar server - Aktifkan perdagangan universal antara server yang berbeda, di mana pengguna dapat menawar barang dengan harga yang berubah secara real-time, dengan peta terurut dari pasangan kunci-nilai.
  • Papan peringkat global - Simpan dan perbarui peringkat pengguna di papan peringkat bersama di dalam peta terurut.
  • Inventaris bersama - Simpan item inventaris dan statistik dalam peta hash bersama, di mana pengguna dapat menggunakan item inventaris secara bersamaan satu sama lain.
  • Cache untuk Data Persisten - Sinkronkan dan salin data persisten Anda di data store ke peta hash penyimpanan memori yang dapat bertindak sebagai cache dan meningkatkan kinerja permainan Anda.

Secara umum, jika Anda perlu mengakses data berdasarkan kunci tertentu, gunakan peta hash. Jika Anda perlu data tersebut diurutkan, gunakan peta terurut. Jika Anda perlu memproses data Anda dalam urutan tertentu, gunakan antrian.

Batasan dan kuota

Untuk mempertahankan skalabilitas dan kinerja sistem, penyimpanan memori memiliki kuota penggunaan data untuk ukuran memori, permintaan API, dan ukuran struktur data.

Penyimpanan memori memiliki kebijakan pengusiran berdasarkan waktu kedaluwarsa, juga dikenal sebagai waktu hidup (TTL). Item akan diusir setelah kedaluwarsa, dan kuota memori dibebaskan untuk entri baru. Ketika Anda mencapai batas memori, semua permintaan tulis berikutnya gagal sampai item kedaluwarsa atau Anda menghapusnya secara manual.

Kuota ukuran memori

Kuota memori membatasi total jumlah memori yang dapat digunakan oleh sebuah permainan. Ini bukan nilai tetap; sebaliknya, ini berubah seiring waktu tergantung pada jumlah pengguna dalam permainan sesuai dengan rumus 64 KB + 1,2 KB * [jumlah pengguna]. Kuota diterapkan pada tingkat permainan, bukan pada tingkat server.

Ketika pengguna bergabung dengan permainan, kuota memori tambahan tersedia segera. Ketika pengguna meninggalkan permainan, kuota tidak langsung berkurang. Ada periode penelusuran selama delapan hari sebelum kuota dievaluasi ulang menjadi nilai yang lebih rendah.

Setelah permainan Anda mencapai kuota ukuran memori, permintaan API yang meningkatkan ukuran memori selalu gagal. Permintaan yang mengurangi atau tidak mengubah ukuran memori tetap berhasil.

Dengan dasbor observabilitas, Anda dapat melihat kuota ukuran memori permainan Anda secara real-time menggunakan grafik Penggunaan Memori.

Batasan permintaan API

Kuota unit permintaan berlaku untuk semua panggilan API MemoryStoreService. Kuota ini adalah 1000 + 120 * [jumlah pengguna bersamaan] unit permintaan per menit.

Sebagian besar panggilan API hanya mengkonsumsi satu unit permintaan, dengan beberapa pengecualian:

  • MemoryStoreSortedMap:GetRangeAsync()

    Mengkonsumsi unit berdasarkan jumlah item yang dikembalikan. Misalnya, jika metode ini mengembalikan 10 item, panggilan dihitung sebagai 10 unit permintaan. Jika mengembalikan respons kosong, dihitung sebagai satu unit permintaan.

  • MemoryStoreQueue:ReadAsync()

    Mengkonsumsi unit berdasarkan jumlah item yang dikembalikan, sama seperti MemoryStoreSortedMap:GetRangeAsync(), tetapi mengkonsumsi satu unit tambahan setiap dua detik saat membaca. Tentukan waktu baca maksimum dengan parameter waitTimeout.

  • MemoryStoreHashMap:UpdateAsync()

    Mengkonsumsi minimal dua unit.

  • MemoryStoreHashMap:ListItemsAsync()

    Mengkonsumsi [jumlah partisi yang dipindai] + [item yang dikembalikan] unit.

Kuota permintaan juga diterapkan pada tingkat permainan, bukan pada tingkat server. Ini memberikan fleksibilitas untuk mengalokasikan permintaan di antara server selama total laju permintaan tidak melebihi kuota. Jika Anda melebihi kuota, Anda akan menerima respons kesalahan ketika layanan membatasi permintaan Anda.

Dengan fitur observabilitas yang tersedia, Anda dapat melihat kuota unit permintaan permainan Anda secara real-time.

Batasan ukuran struktur data

Untuk satu peta terurut atau antrian, batas ukuran dan jumlah item berikut berlaku:

  • Jumlah maksimum item: 1.000.000
  • Ukuran total maksimum (termasuk kunci untuk peta terurut): 100 MB

Batasan per-partisi

Lihat batasan per-partisi.

Praktik terbaik

Untuk menjaga pola penggunaan memori Anda tetap optimal dan menghindari mencapai batasan, ikuti praktik terbaik berikut:

  • Hapus item yang telah diproses. Secara konsisten membersihkan item yang dibaca menggunakan metode MemoryStoreQueue:RemoveAsync() untuk antrian dan MemoryStoreSortedMap:RemoveAsync() untuk peta terurut dapat membebaskan memori dan menjaga struktur data tetap terkini.

  • Tetapkan waktu kedaluwarsa ke rentang waktu terkecil yang mungkin saat menambahkan data. Meskipun waktu kedaluwarsa default adalah 45 hari untuk baik MemoryStoreQueue:AddAsync() maupun MemoryStoreSortedMap:SetAsync(), menetapkan waktu terpendek yang mungkin dapat secara otomatis membersihkan data lama untuk mencegahnya mengisi kuota penggunaan memori Anda.

    • Jangan menyimpan sejumlah besar data dengan waktu kedaluwarsa yang lama, karena berisiko melebihi kuota memori Anda dan berpotensi menyebabkan masalah yang dapat merusak seluruh permainan Anda.
    • Selalu baiknya menghapus item yang tidak diperlukan secara eksplisit atau menetapkan waktu kedaluwarsa item yang pendek.
    • Umumnya, Anda harus menggunakan penghapusan eksplisit untuk membebaskan memori dan waktu kedaluwarsa item sebagai mekanisme pengaman untuk mencegah item yang tidak terpakai mengisi memori dalam jangka waktu yang lama.
  • Hanya simpan nilai yang diperlukan dalam memori.

    Misalnya, untuk permainan rumah lelang, Anda hanya perlu mempertahankan tawaran tertinggi. Anda dapat menggunakan MemoryStoreSortedMap:UpdateAsync() pada satu kunci untuk menjaga tawaran tertinggi daripada menyimpan semua tawaran dalam struktur data Anda.

  • Gunakan backoff eksponensial untuk membantu tetap di bawah batas permintaan API.

    Misalnya, jika Anda menerima DataUpdateConflict, Anda mungkin mencoba lagi setelah dua detik, kemudian empat, delapan, dll. daripada terus-menerus mengirim permintaan ke MemoryStoreService untuk mendapatkan respons yang benar.

  • Pisahkan struktur data besar menjadi beberapa yang lebih kecil dengan sharding.

    Seringkali lebih mudah untuk mengelola data dalam struktur yang lebih kecil daripada menyimpan semuanya dalam satu struktur data besar. Pendekatan ini juga dapat membantu menghindari batasan penggunaan dan laju. Misalnya, jika Anda memiliki peta terurut yang menggunakan awalan untuk kuncinya, pertimbangkan untuk memisahkan setiap awalan ke dalam peta terurutnya sendiri. Untuk permainan yang sangat populer, Anda bahkan mungkin memisahkan pengguna ke dalam beberapa peta berdasarkan digit terakhir dari ID pengguna mereka.

  • Shard kunci yang sering diakses dalam peta hash dengan beberapa salinan kunci untuk mendistribusikan beban.

  • Kompres nilai yang disimpan.

    Misalnya, pertimbangkan untuk menggunakan algoritma LZW untuk mengurangi ukuran nilai yang disimpan.

  • Daftar untuk Layanan Ekstensi.

    Anda dapat meningkatkan kuota Penyimpanan dan Permintaan Anda dengan mendaftar ke Layanan Ekstensi.

Observabilitas

Dasbor Observabilitas memberikan wawasan dan analitik untuk memantau dan memecahkan masalah penggunaan penyimpanan memori Anda. Dengan grafik yang diperbarui secara real-time tentang berbagai aspek penggunaan memori dan permintaan API Anda, Anda dapat melacak pola penggunaan memori permainan Anda, melihat kuota yang dialokasikan saat ini, memantau status API, dan mengidentifikasi masalah potensial untuk optimasi kinerja.

Tabel berikut mencantumkan dan menjelaskan semua kode status dari respons API yang tersedia di grafik Jumlah Permintaan berdasarkan Status dan Permintaan berdasarkan API x Status di Dasbor Observabilitas. Untuk informasi lebih lanjut tentang cara menyelesaikan kesalahan ini, lihat Pemecahan Masalah. Untuk kuota atau batasan spesifik yang terkait dengan kesalahan, lihat Batasan dan Kuota.

Kode statusDeskripsi
BerhasilBerhasil.
DataStructureMemoryOverLimitMelebihi batas ukuran memori tingkat struktur data (100 MB).
DataUpdateConflictKonflik karena pembaruan bersamaan.
AccessDeniedTidak berwenang untuk mengakses data permainan. Permintaan ini tidak mengkonsumsi unit permintaan atau menggunakan kuota.
InternalErrorKesalahan internal.
InvalidRequestPermintaan tidak memiliki informasi yang diperlukan atau memiliki informasi yang salah format.
DataStructureItemsOverLimitMelebihi batas jumlah item tingkat struktur data (1M).
NoItemFoundTidak ada item yang ditemukan di MemoryStoreQueue:ReadAsync() atau MemoryStoreSortedMap:UpdateAsync(). ReadAsync() memeriksa setiap 2 detik dan mengembalikan kode status ini sampai menemukan item di antrian.
DataStructureRequestsOverLimitMelebihi batas unit permintaan tingkat struktur data (100.000 unit permintaan per menit).
PartitionRequestsOverLimitMelebihi batas unit permintaan partisi.
TotalRequestsOverLimitMelebihi batas unit permintaan tingkat semesta.
TotalMemoryOverLimitMelebihi kuota memori tingkat semesta.
ItemValueSizeTooLargeUkuran nilai melebihi batas (32 KB).

Tabel berikut mencantumkan kode status dari sisi klien, yang saat ini tidak tersedia di Dasbor Observabilitas.

Kode statusDeskripsi
InternalErrorKesalahan Internal.
UnpublishedPlaceAnda harus menerbitkan tempat ini untuk menggunakan MemoryStoreService.
InvalidClientAccessMemoryStoreService harus dipanggil dari server.
InvalidExpirationTimeWaktu kedaluwarsa 'expiration' harus antara 0 dan 3.888.000.
InvalidRequestTidak dapat mengonversi nilai ke json.
InvalidRequestTidak dapat mengonversi sortKey menjadi angka atau string yang valid.
TransformCallbackFailedGagal memanggil fungsi callback transformasi.
RequestThrottledPermintaan MemoryStores baru-baru ini mencapai satu atau lebih batas.
UpdateConflictMelebihi jumlah maksimum percobaan.

Pemecahan Masalah

Tabel berikut mencantumkan dan menjelaskan solusi yang direkomendasikan untuk setiap kode status respons:

KesalahanOpsi pemecahan masalah
DataStructureRequestsOverLimit / PartitionRequestsOverLimit
  • Tambahkan cache lokal dengan menyimpan informasi ke variabel lain dan memeriksa kembali setelah interval waktu tertentu, seperti 30 detik.
  • Gunakan grafik Jumlah Permintaan berdasarkan Status untuk memverifikasi bahwa Anda menerima lebih banyak respons Berhasil daripada NoItemFound. Batasi jumlah kali Anda mengakses MemoryStoreService dengan permintaan yang gagal.
  • Implementasikan jeda singkat antara permintaan.
  • Ikuti praktik terbaik, termasuk:
    • Sharding struktur data Anda jika Anda menerima sejumlah besar respons DataStructureRequestsOverLimit/PartitionRequestsOverLimit.
    • Sharding kunci peta hash Anda jika Anda menerima sejumlah besar respons PartitionRequestsOverLimit pada panggilan peta hash.
    • Mengurangi atau mengelompokkan panggilan ke struktur data tertentu atau kunci peta hash jika Anda melihat respons PartitionRequestsOverLimit.
    • Implementasikan backoff eksponensial untuk menemukan laju permintaan yang wajar untuk dikirim.
TotalRequestsOverLimit
DataStructureItemsOverLimit
DataStructureMemoryOverLimit
TotalMemoryOverLimit
DataUpdateConflict
  • Implementasikan jeda singkat antara permintaan untuk menghindari beberapa permintaan yang memperbarui kunci yang sama pada saat yang sama.
  • Untuk peta terurut, gunakan fungsi callback pada metode MemoryStoreSortedMap:UpdateAsync() untuk membatalkan permintaan setelah sejumlah percobaan tertentu, seperti yang ditunjukkan dalam contoh kode berikut:
  • Contoh Membatalkan Permintaan
    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")
  • Selidiki untuk melihat apakah Anda memanggil MemoryStoreService secara efisien untuk menghindari konflik. Idealnya, Anda tidak boleh mengirim permintaan secara berlebihan.
  • Secara konsisten hapus item setelah dibaca menggunakan metode MemoryStoreQueue:RemoveAsync() untuk antrian dan MemoryStoreSortedMap:RemoveAsync() untuk peta terurut.
Kesalahan Internal
InvalidRequest
  • Pastikan Anda menyertakan parameter yang benar dan valid dalam permintaan Anda. Contoh parameter yang tidak valid termasuk:
    • String kosong
    • String yang melebihi batas panjang
ItemValueSizeTooLarge
  • Shard atau pisahkan nilai item menjadi beberapa kunci.
    • Untuk mengatur kunci yang dikelompokkan, urutkan mereka secara alfabetis dengan menambahkan prefix ke kunci.
  • Encoding atau mengompresi nilai yang disimpan.

Uji dan debug di Studio

Data dalam MemoryStoreService terisolasi antara Studio dan produksi, jadi mengubah data di Studio tidak mempengaruhi perilaku produksi. Ini berarti bahwa panggilan API Anda dari Studio tidak mengakses data produksi, memungkinkan Anda untuk menguji penyimpanan memori dan fitur baru dengan aman sebelum masuk ke produksi.

Pengujian Studio memiliki batasan dan kuota yang sama seperti produksi. Untuk kuota yang dihitung berdasarkan jumlah pengguna, kuota yang dihasilkan bisa sangat kecil karena Anda adalah satu-satunya pengguna untuk pengujian Studio. Saat menguji dari Studio, Anda mungkin juga memperhatikan latensi yang sedikit lebih tinggi dan tingkat kesalahan yang meningkat dibandingkan dengan penggunaan di produksi karena beberapa pemeriksaan tambahan yang dilakukan untuk memverifikasi akses dan izin.

Untuk informasi tentang cara melakukan debug penyimpanan memori di permainan langsung atau saat menguji di studio, gunakan Konsol Pengembang.

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