Redis'te canlı leaderboard için neden Sorted Set kullanmalıyım?
Soru
Bir oyun platformu için canlı leaderboard (en yüksek skorlu ilk 100 oyuncu) tasarlayacağım; milyonlarca oyuncunun skoru anlık değişiyor. Veriyi Redis'te tutmak istiyorum. Her oyuncunun skorunu düz bir String anahtarda (`user:123:score`) tutup her seferinde tüm kullanıcıları çekip sıralamak yerine Redis'in Sorted Set (ZSET) veri tipini kullanmanın mimari avantajları ve zaman karmaşıklığı (O(log N)) analizi nedir?
Cevap
Kısa cevap: Skorları user:123:score gibi düz String’lerde tutup uygulamada sıralama — bu okuma başına milyonlarca anahtar üzerinde O(N log N), üstelik her seferinde her şeyi yeniden çekersin. Doğru araç Sorted Set (ZSET).
Asıl mesele şu: leaderboard’ın doğası “sırala ve ilk N’i ver”. Bu işi okuma anında yapmaya çalışırsan ölçek seni ezer; sıralamayı yazma anına taşıman gerekir.
ZADDile O(log N) güncelleme.ZADD leaderboard <score> <user>bir üyenin skorunu O(log N)‘de günceller. Oyuncu skoru değiştiğinde tek komut; tüm tabloyu dokunmana gerek yok. Skor değiştiği an set kendi içinde sıralı kalır.ZREVRANGEile zaten sıralı ilk 100.ZREVRANGE leaderboard 0 99 WITHSCORESen yüksek 100 oyuncuyu zaten sıralı olarak O(log N + 100)‘de döner. Uygulama tarafında hiç sıralama yapmazsın; milyonlarca oyuncu olsa da bu okuma neredeyse sabit maliyetli.ZREVRANKile tek oyuncunun sırası. “Ben kaçıncıyım?” sorusuZREVRANK leaderboard <user>ile O(log N)‘de cevaplanır. String yaklaşımında bunun için herkesi çekip saymak gerekirdi; ZSET’te tek komut.- Skip-list, sıralamayı yazarken yapar. ZSET’in arkasındaki skip-list yapısı her şeyi sen yazdıkça sıralı tutar. Yani maliyet okuma anına değil yazma anına dağılır; okuma ucuz ve oyuncu sayısından neredeyse bağımsız kalır.
- Büyük setlerde pencerele. Devasa setler için periyodik snapshot’lar ve zaman pencereli board’lar (günlük/haftalık ayrı anahtarlar) kullan. Eşitliklere dikkat: aynı skorlular lexicographic sıralanır; gerekiyorsa skora bir tiebreaker (örn. zaman damgası) gömerek sırayı deterministik yap.
Sonuç: ZSET tam da canlı leaderboard için tasarlanmış bir veri tipi; String + uygulama tarafı sıralama yerine onu kullan. Sıralamayı okuma anından alıp yazma anına taşıdığın an, milyonlarca oyuncuda bile leaderboard’ın anlık ve ucuz çalışır.
Yorumlar
Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.