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 memori cepat yang dapat diakses dari semua server dalam sesi yang aktif. Penyimpanan Memori cocok untuk data yang sering dan sementara yang berubah dengan cepat dan tidak perlu bersifat tahan lama, karena lebih cepat diakses dan menghilang saat mencapai umur 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 yang cepat: peta terurut, antrian, dan peta hash. Setiap struktur data cocok untuk kasus penggunaan tertentu:

  • Pemilihan berdasarkan keterampilan - Simpan informasi pengguna, seperti tingkat keterampilan, dalam antrian yang dibagikan di antara server, dan gunakan server lobi untuk menjalankan pemilihan secara berkala.
  • Perdagangan dan pelelangan antar server - Mengizinkan perdagangan universal antara berbagai server, di mana pengguna dapat menawar item dengan harga yang berubah secara real-time, dengan peta terurut pasangan kunci-nilai.
  • Papan peringkat global - Simpan dan perbarui peringkat pengguna di papan peringkat yang dibagikan di dalam peta terurut.
  • Inventaris bersama - Simpan item inventaris dan statistik dalam peta hash yang dibagikan, di mana pengguna dapat memanfaatkan item inventaris secara bersamaan.
  • 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 game Anda.

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

Batas 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 dikeluarkan 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 game. Ini bukan nilai tetap; sebaliknya, berubah seiring waktu tergantung pada jumlah pengguna dalam game sesuai dengan rumus 64KB + 1.2KB * [jumlah pengguna]. Kuota diterapkan di level game, bukan di level server.

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

Setelah game 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 game Anda secara real-time menggunakan grafik Penggunaan Memori.

Batas 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 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 di level game, bukan di level server. Ini memberikan fleksibilitas untuk mendistribusikan permintaan di antara server selama total laju permintaan tidak melebihi kuota. Jika Anda melebihi kuota, Anda akan menerima respons kesalahan saat layanan mengurangi permintaan Anda.

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

Batas 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

Batas per-partisi

Lihat batas per-partisi.

Praktik terbaik

Untuk menjaga pola penggunaan memori Anda tetap optimal dan menghindari mencapai batas, 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.

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

    • Jangan menyimpan sejumlah besar data dengan waktu kedaluwarsa yang panjang, karena ada risiko melebihi kuota memori Anda dan berpotensi menyebabkan masalah yang dapat merusak seluruh game Anda.
    • Selalu hapus item yang tidak diperlukan secara eksplisit atau tetapkan kedaluwarsa item yang pendek.
    • Secara umum, Anda harus menggunakan penghapusan eksplisit untuk membebaskan memori dan kedaluwarsa item sebagai mekanisme keamanan untuk mencegah item yang tidak terpakai menghabiskan memori dalam waktu yang lama.
  • Hanya simpan nilai yang diperlukan dalam memori.

    Misalnya, untuk game 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 kembali 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 penyerpihan.

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

  • Shard kunci yang diakses sering 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 yang Diperpanjang.

    Anda dapat meningkatkan kuota Penyimpanan dan Permintaan Anda dengan bergabung ke Layanan yang Diperpanjang.

Observabilitas

Dasbor Observabilitas memberikan wawasan dan analisis untuk memantau dan memecahkan masalah penggunaan penyimpanan memori Anda. Dengan grafik yang diperbarui secara real-time tentang berbagai aspek penggunaan memori Anda dan permintaan API, Anda dapat melacak pola penggunaan memori game 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 Observabilitas Dashboard. Untuk informasi lebih lanjut tentang cara menyelesaikan kesalahan ini, lihat Pemecahan Masalah. Untuk kuota atau batas tertentu yang terkait dengan kesalahan, lihat Batas dan Kuota.

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

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' 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 yang 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 ulang setelah jeda waktu tertentu, seperti 30 detik.
  • Gunakan grafik Jumlah Permintaan berdasarkan Status untuk memverifikasi bahwa Anda menerima lebih banyak respons Berhasil daripada Tidak Ada Item Ditemukan. Batasi jumlah kali Anda menyerang MemoryStoreService dengan permintaan yang gagal.
  • Implementasikan jeda singkat antara permintaan.
  • Ikuti praktik terbaik, termasuk:
    • Melakukan penyerpihan pada struktur data Anda jika Anda menerima sejumlah besar respons DataStructureRequestsOverLimit/PartitionRequestsOverLimit.
    • Melakukan penyerpihan pada 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 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 adalah "..item.highestBid)
    return nil
    end, 1000)
    end
    placeBid("MyItem", 50)
    placeBid("MyItem", 40)
    print("selesai")
  • Selidiki untuk melihat apakah Anda memanggil MemoryStoreService secara efisien untuk menghindari konflik. Idealnya, Anda seharusnya tidak 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 meliputi:
    • String kosong
    • String yang melebihi batas panjang
ItemValueSizeTooLarge
  • Pecah atau bagi nilai item menjadi beberapa kunci.
    • Untuk mengatur kunci yang dikelompokkan, urutkan secara alfabetis dengan menambahkan prefix pada kunci.
  • Penyandian atau kompresi 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 batas dan kuota yang sama dengan produksi. Untuk kuota yang dihitung berdasarkan jumlah pengguna, kuota yang dihasilkan mungkin sangat kecil karena Anda adalah satu-satunya pengguna untuk pengujian Studio. Saat menguji dari Studio, Anda mungkin juga melihat latensi sedikit lebih tinggi dan tingkat kesalahan yang meningkat dibandingkan penggunaan di produksi karena beberapa pemeriksaan tambahan yang dilakukan untuk memverifikasi akses dan izin.

Untuk informasi tentang cara melakukan debug penyimpanan memori pada game live 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.