MemoryStoreService, canlı bir oturumda tüm sunuculardan erişilebilen hızlı bellek içi veri depolama sağlayan yüksek verimli ve düşük gecikmeli bir veri hizmetidir. Bellek Depoları, sık değişen ve kalıcı olmaları gerekmeyen geçici veriler için uygundur, çünkü erişim açısından daha hızlıdırlar ve maksimum ömre ulaştıklarında kaybolurlar. Oturumlar arasında kalıcı olması gereken veriler için veri depolarını kullanın.
Veri yapıları
Ham verilere doğrudan erişmek yerine, bellek depoları hızlı işleme için sunucular arasında paylaşılan üç temel veri yapısına sahiptir: sıralı harita, kuyruk ve hash harita. Her veri yapısı belirli kullanım durumları için iyi bir uyum sağlar:
- Yetenek bazlı eşleştirme - Kullanıcı bilgilerini, örneğin yetenek seviyesini, sunucular arasında paylaşılan bir kuyrukta saklayın ve eşleştirmeyi periyodik olarak yürütmek için lobideki sunucuları kullanın.
- Sunucular arası ticaret ve açık artırma - Kullanıcıların gerçek zamanlı değişen fiyatlarla öğelere teklif verebileceği, farklı sunucular arasında evrensel ticareti etkinleştirin; bir sıralı harita ile anahtar-değer çiftleri.
- Küresel liderlik tabloları - Kullanıcı sıralamalarını paylaşılan bir liderlik tablosunda bir sıralı harita içinde saklayın ve güncelleyin.
- Paylaşılan envanterler - Kullanıcıların birbirleriyle eşzamanlı olarak envanter öğelerini kullanabileceği bir paylaşılan hash harita içinde envanter öğelerini ve istatistiklerini saklayın.
- Kalıcı Veriler için Önbellek - Kalıcı verilerinizi bir veri deposunda senkronize edin ve kopyalayın, böylece bir bellek deposu hash haritası olarak önbellek işlevi görebilir ve oyununuzun performansını artırabilir.
Genel olarak, belirli bir anahtara dayalı verilere erişmeniz gerekiyorsa, bir hash harita kullanın. Verinin sıralı olmasını istiyorsanız, bir sıralı harita kullanın. Verilerinizi belirli bir sırada işlemek istiyorsanız, bir kuyruk kullanın.
Sınırlamalar ve kotalar
Ölçeklenebilirliği ve sistem performansını korumak için, bellek depolarının bellek boyutu, API istekleri ve veri yapısı boyutu için veri kullanımı kotaları vardır.
Bellek depoları, son kullanma süresine dayalı bir tahliye politikası uygular; bu, yaşam süresi (TTL) olarak da bilinir. Öğeler süresi dolduğunda tahliye edilir ve bellek kotası yeni girişler için serbest bırakılır. Bellek sınırına ulaştığınızda, tüm sonraki yazma istekleri, öğeler süresi dolana kadar veya manuel olarak silinene kadar başarısız olur.
Bellek boyutu kotası
Bellek kotası, bir oyunun tüketebileceği toplam bellek miktarını sınırlar. Sabit bir değer değildir; bunun yerine, oyundaki kullanıcı sayısına bağlı olarak zamanla değişir ve formül 64 KB + 1.2 KB * [kullanıcı sayısı] şeklindedir. Kota, sunucu düzeyinde değil, oyun düzeyinde uygulanır.
Kullanıcılar oyuna katıldığında, ek bellek kotası hemen kullanılabilir hale gelir. Kullanıcılar oyundan ayrıldığında, kota hemen düşmez. Kota daha düşük bir değere yeniden değerlendirene kadar sekiz günlük bir geri izleme süresi vardır.
Oyununuza bellek boyutu kotası aşıldığında, bellek boyutunu artıran herhangi bir API isteği her zaman başarısız olur. Bellek boyutunu azaltan veya değiştirmeyen istekler ise yine de başarılı olur.
Gözetim panosuyla, oyununuzun bellek boyutu kotasını gerçek zamanlı olarak Bellek Kullanımı grafiği ile görüntüleyebilirsiniz.
API istek limitleri
Bir istek birimi kotası, tüm MemoryStoreService API çağrılarına uygulanır. Bu kota, 1000 + 120 * [eşzamanlı kullanıcı sayısı] istek birimi dakikada geçerlidir.
Çoğu API çağrısı yalnızca bir istek birimi tüketir, birkaç istisna ile:
MemoryStoreSortedMap:GetRangeAsync()
Döndürülen öğe sayısına göre birim tüketir. Örneğin, bu yöntem 10 öğe döndürürse, çağrı 10 istek birimi olarak sayılır. Eğer boş bir yanıt dönerse, bir istek birimi olarak sayılır.
Döndürülen öğe sayısına göre birim tüketir, MemoryStoreSortedMap:GetRangeAsync() gibi, ancak okuma sırasında her iki saniyede bir ek birim tüketir. Maksimum okuma süresini waitTimeout parametresi ile belirtin.
MemoryStoreHashMap:UpdateAsync()
En az iki birim tüketir.
MemoryStoreHashMap:ListItemsAsync()
[tarayıcı bölümleri] + [döndürülen öğeler] birim tüketir.
İstek kotası, sunucu düzeyinde değil, oyun düzeyinde de uygulanır. Bu, toplam istek oranı kotayı aşmadığı sürece sunucular arasında istekleri dağıtma esnekliği sağlar. Kota aşıldığında, isteklerinizin kısıtlandığı zaman bir hata yanıtı alırsınız.
Gözetim özelliği ile, oyununuzun istek birimi kotasını gerçek zamanlı olarak görüntüleyebilirsiniz.
Veri yapısı boyutu limitleri
Tek bir sıralı harita veya kuyruk için aşağıdaki boyut ve öğe sayısı limitleri geçerlidir:
- Maksimum öğe sayısı: 1,000,000
- Maksimum toplam boyut (sıralı harita için anahtarlar dahil): 100 MB
Bölüm başına limitler
Oyun düzeyindeki istek birimi kotası dışında, bellek depoları her bölüme istek limitleri uygular; bu, tüm oyunlar için hizmetin kararlılığını koruyan bir güvenlik önlemidir. Bu limitler, oyununuzun tahsis edilen bir kotası değildir ve oyununuzun ulaşabileceği verimlilikte sert bir tavan değildir. Aşağıdaki değerler tahminidir. Roblox arka uçta yapılandırılmıştır ve değişebilir, bu nedenle bunları sabit sayılar olarak tasarlamayın.
Her istek, öğeyi tutan bölüm limitine sayılır, veri yapısı ne olursa olsun. Şu anda, tek bir bölüm için yaklaşık 30,000 istek birimi dakikada kısıtlamanın başlamasını bekleyebilirsiniz, bu nedenle bu oranı oldukça altında kalmaya çalışın. Bir veri yapısının bu limitten ne kadarını tüketeceği, öğelerinin nasıl dağıtıldığına bağlıdır:
- Sıralı haritalar ve kuyruklar her biri tek bir bölümde bulunur, bu nedenle bu veri yapılarına yapılan her istek aynı bölüm limitine sayılır.
- Hash haritaları öğelerini birçok bölüme yayar, bu nedenle birçok öğe anahtarı arasında dağıtılan trafik, herhangi bir bölümün limitine nadiren yaklaşır.
Hash haritalarının her öğe anahtarı için yaklaşık 5,000 yazma istek birimi dakikada ve 15,000 okuma istek birimi dakikada ek bir limiti vardır. Bu anahtar başına limit, bölüm başına limitin üzerine uygulanır, bu nedenle sık erişilen bir anahtar her ikisini de aşabilir. Anahtar başına limit yalnızca tek anahtar işlemlerine uygulanır: okuma limiti MemoryStoreHashMap:GetAsync(), yazma limiti MemoryStoreHashMap:SetAsync() ve MemoryStoreHashMap:RemoveAsync(), ve MemoryStoreHashMap:UpdateAsync() hem okuma hem de yazma limitlerine karşı sayılır. MemoryStoreHashMap:ListItemsAsync() bölümleri tarar, bu nedenle yalnızca bölüm başına limit buna uygulanır.

Eğer sıralama veya ilk giren ilk çıkar işlevselliğine ihtiyacınız yoksa, genellikle bir hash harita en iyi seçimdir çünkü yükü bölümler arasında yayabilir.
İstekler bir bölüm veya anahtar başına limiti aştığında, hizmet bunları kısıtlar ve PartitionRequestsOverLimit durum kodunu döndürür; bunu gözetim panosuyla izleyebilirsiniz.
Bir veri yapısının veya bir öğe anahtarının yüksek, sürekli bir istek oranı almasını bekliyorsanız, shard yaparak yükü daha fazla bölüme veya anahtara yayabilirsiniz. Okuma ve yazmaları, anahtar başına limitler içinde kalmak için birden fazla öğe anahtarı arasında eşit şekilde dağıtın. Ayrıca, sunucuda değerleri önbelleğe alarak ve bir süre sonra yeniden kontrol ederek, mümkün olduğunda istekleri toplu halde yaparak ve kısıtlama yanıtları aldığınızda üstel geri çekilme uygulayarak istek oranını azaltabilirsiniz.
En iyi uygulamalar
Bellek kullanım deseninizi optimal tutmak ve sınırlara ulaşmaktan kaçınmak için bu en iyi uygulamaları izleyin:
İşlenmiş öğeleri kaldırın. MemoryStoreQueue:RemoveAsync() yöntemi ile kuyruklar için ve MemoryStoreSortedMap:RemoveAsync() ile sıralı haritalar için okunan öğeleri sürekli temizlemek, belleği serbest bırakabilir ve veri yapısını güncel tutabilir.
Veri eklerken son kullanma süresini mümkün olan en kısa zaman dilimine ayarlayın. MemoryStoreQueue:AddAsync() ve MemoryStoreSortedMap:SetAsync() için varsayılan son kullanma süresi 45 gündür, ancak mümkün olan en kısa süreyi ayarlamak, eski verilerin otomatik olarak temizlenmesini sağlayarak bellek kullanım kotanızı doldurmalarını önleyebilir.
- Uzun bir son kullanma süresi ile büyük miktarda veri saklamayın, çünkü bu bellek kotanızı aşma riski taşır ve bu da oyununuzun tamamını bozabilecek sorunlara yol açabilir.
- Her zaman ya gereksiz öğeleri açıkça silin ya da kısa bir öğe son kullanma süresi ayarlayın.
- Genel olarak, belleği serbest bırakmak için açık silme kullanmalısınız ve kullanılmayan öğelerin uzun süre bellek kaplamasını önlemek için bir güvenlik mekanizması olarak öğe son kullanma süresini kullanmalısınız.
Bellekte yalnızca gerekli değerleri tutun.
Örneğin, bir açık artırma evi oyunu için yalnızca en yüksek teklifi korumanız gerekir. Tüm teklifleri veri yapınızda tutmak yerine, en yüksek teklifi korumak için bir anahtar üzerinde MemoryStoreSortedMap:UpdateAsync() kullanabilirsiniz.
API istek limitlerinin altında kalmanıza yardımcı olmak için üstel geri çekilme kullanın.
Örneğin, bir DataUpdateConflict aldığınızda, iki saniye sonra yeniden deneyebilir, ardından dört, sekiz vb. yapabilirsiniz; sürekli olarak MemoryStoreService'e doğru yanıt almak için istek göndermek yerine.
Devasa veri yapılarını sharding ile birden fazla daha küçük yapıya ayırın.
Verileri daha küçük yapılarda yönetmek genellikle daha kolaydır; her şeyi tek bir büyük veri yapısında saklamak yerine. Bu yaklaşım, kullanım ve oran limitlerinden kaçınmanıza da yardımcı olabilir. Örneğin, anahtarları için önekler kullanan bir sıralı haritanız varsa, her öneki kendi sıralı haritasına ayırmayı düşünün. Özellikle popüler bir oyun için, kullanıcıları kullanıcı kimliklerinin son rakamlarına göre birden fazla haritaya ayırmayı bile düşünebilirsiniz.
Sık erişilen anahtarları hash haritalarında birden fazla anahtar kopyası ile shard yapın.
Saklanan değerleri sıkıştırın.
Örneğin, saklanan değer boyutunu azaltmak için LZW algoritmasını kullanmayı düşünün.
Genişletilmiş Hizmetler'e kaydolun.
Genişletilmiş Hizmetler ile depolama ve istek limitlerinizi artırabilirsiniz.
Gözetim
Gözetim Panosu, bellek deposu kullanımınızı izlemek ve sorun gidermek için içgörüler ve analizler sağlar. Bellek kullanımınızın ve API isteklerinizin farklı yönleri hakkında gerçek zamanlı güncellenen grafiklerle, oyununuzun bellek kullanım desenini takip edebilir, mevcut tahsis edilen kotaları görüntüleyebilir, API durumunu izleyebilir ve performans optimizasyonu için potansiyel sorunları belirleyebilirsiniz.
Aşağıdaki tablo, Gözetim Panosu'ndaki Duruma Göre İstek Sayısı ve API x Duruma Göre İstekler grafiklerinde mevcut olan API yanıtlarının tüm durum kodlarını listeler ve açıklar. Bu hataları nasıl çözeceğiniz hakkında daha fazla bilgi için Sorun Giderme bölümüne bakın. Bir hatanın ilişkili olduğu belirli kota veya limit için Sınırlamalar ve Kotalar bölümüne bakın.
| Durum kodu | Açıklama |
|---|---|
| Başarılı | Başarılı. |
| DataStructureMemoryOverLimit | Veri yapısı düzeyindeki bellek boyutu limitini aşıyor (100 MB). |
| DataUpdateConflict | Eşzamanlı güncelleme nedeniyle çakışma. |
| Erişim Reddedildi | Oyun verilerine erişim yetkisi yok. Bu istek, istek birimlerini tüketmez veya kota kullanmaz. |
| İç Hata | İç hata. |
| Geçersiz İstek | İstek gerekli bilgilere sahip değil veya hatalı bilgilere sahip. |
| DataStructureItemsOverLimit | Veri yapısı düzeyindeki öğe sayısı limitini aşıyor (1M). |
| Hiçbir Öğe Bulunamadı | MemoryStoreQueue:ReadAsync() veya MemoryStoreSortedMap:UpdateAsync() içinde hiçbir öğe bulunamadı. ReadAsync() her 2 saniyede bir anket yapar ve kuyrukta öğe bulana kadar bu durum kodunu döndürür. |
| DataStructureRequestsOverLimit | Veri yapısı düzeyindeki istek birimi limitini aşıyor (dakikada 100,000 istek birimi). |
| PartitionRequestsOverLimit | bölüm başına veya anahtar başına istek birimi limitini aşıyor. |
| TotalRequestsOverLimit | Evren düzeyindeki istek birimi limitini aşıyor. |
| TotalMemoryOverLimit | Evren düzeyindeki bellek kotasını aşıyor. |
| ItemValueSizeTooLarge | Değer boyutu limitini aşıyor (32 KB). |
Aşağıdaki tablo, şu anda Gözetim Panosu'nda mevcut olmayan istemci tarafı durum kodlarını listeler.
| Durum kodu | Açıklama |
|---|---|
| İç Hata | İç Hata. |
| Yayınlanmamış Yer | MemoryStoreService'i kullanmak için bu yeri yayınlamanız gerekir. |
| Geçersiz İstemci Erişimi | MemoryStoreService sunucudan çağrılmalıdır. |
| Geçersiz Son Kullanma Süresi | 'expiration' alanı süresi 0 ile 3,888,000 arasında olmalıdır. |
| Geçersiz İstek | Değeri json'a dönüştürmek mümkün değil. |
| Geçersiz İstek | sortKey'i geçerli bir sayı veya dizeye dönüştürmek mümkün değil. |
| Dönüşüm Geri Çağırma Başarısız | Dönüşüm geri çağırma işlevini çağırmak başarısız oldu. |
| İstek Kısıtlandı | Son zamanlarda MemoryStores istekleri bir veya daha fazla sınıra ulaştı. |
| Güncelleme Çakışması | Maksimum yeniden deneme sayısını aştı. |
Sorun Giderme
Aşağıdaki tablo, her yanıt durum kodu için önerilen çözümü listeler ve açıklar:
| Hata | Sorun Giderme seçenekleri |
|---|---|
| DataStructureRequestsOverLimit / PartitionRequestsOverLimit |
|
| TotalRequestsOverLimit | |
| DataStructureItemsOverLimit |
|
| DataStructureMemoryOverLimit | |
| TotalMemoryOverLimit | |
| DataUpdateConflict |
İsteği İptal Etme Örneği |
| İç Hata |
|
| Geçersiz İstek |
|
| ItemValueSizeTooLarge |
|
Stüdyoda test etme ve hata ayıklama
MemoryStoreService içindeki veriler, Stüdyo ve üretim arasında izole edilmiştir, bu nedenle Stüdyodaki verileri değiştirmek, üretim davranışını etkilemez. Bu, Stüdyodan yaptığınız API çağrılarının üretim verilerine erişmediği anlamına gelir; böylece bellek depolarını ve yeni özellikleri üretime geçmeden önce güvenle test edebilirsiniz.
Stüdyo testi, üretimdekiyle aynı sınırlara ve kotalara sahiptir. Kullanıcı sayısına dayalı olarak hesaplanan kotalar için, sonuçta oluşan kota çok küçük olabilir, çünkü Stüdyo testi için tek kullanıcı sizsiniz. Stüdyodan test yaparken, ayrıca erişim ve izinleri doğrulamak için gerçekleştirilen bazı ek kontroller nedeniyle üretimdeki kullanıma kıyasla biraz daha yüksek gecikme ve artan hata oranları da gözlemleyebilirsiniz.
Canlı oyunlarda veya stüdyoda bir bellek deposunu nasıl hata ayıklayacağınız hakkında bilgi için Geliştirici Konsolu kullanın.