MMORPG gibi dinamik bir dünyayı yatay olarak ölçeklenebilir yapmanın bir yolu var mı?


11

20 güncelleme / oyuncu / saniye hızında veri değişen 500'den fazla oyuncunun açık dünyasını hayal edin. Son kez benzer bir MMORPG'de çalıştım, SQL kullandı, bu yüzden obvioulsy DB'yi her zaman sorgulayamadı. Bunun yerine, DB'den tüm oyuncuları C ++ nesneleri olarak belleğe yükledi ve kullandı. Yani dikey olarak ölçeklendi. Bunun yerine sunucuyu yatay olarak ölçeklendirilebilir mi? Bu miktarda güncellemeyi aynı anda destekleyecek şekilde tasarlanmış bir veritabanı var mı?


Veritabanındaki oynatıcıyı neden saniyede 20 kez güncellemek istiyorsunuz?
Balon

@Balon kafam karıştı. Veritabanında, sadece bellekte güncellemezsem, farklı makineler arasında farklı durumlar olur. Ama sanırım DB güncellemelerinin büyük bir yükü var, bu yüzden bu miktar güncellemeler için işe yaramayacak mı?
MaiaVictor

2
Gerçekten, gerçekten farklı makinelerin (hatta süreçlerin) yüzlerce nesne üzerinde 20Hz güncellemeye ihtiyacı olduğunu düşünüyorsanız, veritabanını tamamen atlayın ve doğrudan bir mesajlaşma sistemi kullanın. Ama gerçekten istediğiniz, gerçekten istediğinizi düşündüğünüz şey gerçekten istediğiniz şey değil. İstediğiniz şey, kimin neyi bilmesi gerektiğine dair aklı bir alana sahip olmak ve daha sonra nesneleri kapsamlar arasında düzgün bir şekilde taşımanın bir yoluna sahip olmaktır. Harika yanıtlar için neden farklı makineler arasında 20Hz güncellemelerine ihtiyacınız olduğu sorusunu yanıtlamalısınız, birisi soruna bakmak için yeni bir yol düşünebilir.
Patrick Hughes

@PatrickHughes Neye ihtiyacım olduğunu bilmiyorum, sadece oyunun nasıl çalıştığını açıklıyorum. Karakterler saniyede 2 ~ 3 kare taşır. Bir oyuncu avı birkaç canavarla çevrili olabilir, bu yüzden en az 10 taş / oyuncu / saniye. Sonra yerde, oyuncunun sırt çantasında çürüyen eşyalar var. Oyuncunun yönünde hareket eden saldırılar var, canavarın yönünde hareket eden saldırılar var. Sağlığa çürüme, kullanılan mana, oyuncuya zehir hasarı uygulayan zamanlayıcılar var. Yani işler çok hızlı değişiyor. Bu oyun tasarımı. Böyle bir tasarım dikey olarak nasıl ölçeklendirilebilir?
MaiaVictor

1
Bunu biraz önce HackerNews'de gördüm: paralleluniverse.co Onlar sizin için tüm uzamsal segmentasyon / dağıtım şeylerini yapan bir veritabanı üzerinde çalışıyorlar. Tahmin ediyorum ki, aşağıdaki cevaplardaki her şeyi yapıyorlar.
römorkörler

Yanıtlar:


17

Test eden 500 oyuncunun test durumu, 20Hz'de 250K bilgi akışı. Bunun için dahili bant genişliği, her mesajın 100 bayt olduğu varsayıldığında, yaklaşık 500MB / sn olacaktır. Kulağa hırslı geliyor. Özellikle süreçler arasında.

Oyuncuları 100'lük gruplara ayırırsanız, bu 20MB / sn'ye düşer ve bu böyle devam eder. MMO'ların bölgelere sahip olmasının nedeni budur ve bu bölgelerde küçük etki kabarcıkları vardır ve bant genişliği makul hale gelene kadar aşağı doğru devam eder.

Asıl sorun, gerçek zamanlı bilgi paylaşan 10 kişiniz varsa, ancak 500 paylaşım paylaşmak istiyorsanız , bunun iletişim bağlantılarının katlanarak arttığı ve bunun nasıl üstesinden gelebileceğimiz söylenebilir . Korkarım, sihirli bir şekilde geometrik ilerlemeyi ortadan kaldırabilecek sihirli bir mermi yok.

İletişim kurmak için veritabanı kullanmayın, mesajlaşma budur. İşlemleri uygulamak ve oyuncuların kaybetmesini istemediğiniz bilgileri depolamak için veritabanını kullanın. Bildiğim çoğu MMO, veritabanını yalnızca 1-10 dakikada bir dinamik oynatıcı bilgileriyle veya bölge geçişleri veya tasarımda "güvenli" bölgeler girme gibi kullanışlı noktalarda günceller.

Oyunun her oyuncuya olan ihtiyacını , ne kadar uzakta olursa olsun, diğer tüm oyuncuların sırt çantası içeriğiyle ilgili gerçek zamanlı güncellemelere sahip olacak şekilde yeniden tasarlamanız gerekebilir .

Ayrıca güncelleme desenini 20Hz'den hıza göre bir hıza değiştirin, 1 mil uzakta birinin tam olarak 230.6 saniyede 1 ayağınızı, ardından 231.4 saniyede başka bir ayağınızı hareket ettirdiğinizi bilmesine gerek yoktur, saniye.


Müthiş ve bilgilendirici cevap, teşekkürler. Ancak şunu ekleyebilirim ki, dünya çok hızlı bir şekilde değişirken, bir oyuncu sadece hemen yanındaki diğer oyuncuları görebilir. Geometrik olarak görmüyorum - 500 oyuncu sunucuya bilgi gönderiyor; sunucu periyodik olarak bu 500 oyuncuya bilgi gönderir. Gördüğüm gibi doğrusal. Ama asıl nokta 4. paragrafta: Eğer sadece depolama için veritabanını kullanırsam, o zaman veriyi belleğe yüklüyorum. Bir makinedeki belleğe veri yüklüyorsam, dünyanın senkronize olmayan bir sürümünü oluşturuyorum. Almadýđým bu.
MaiaVictor

1 istemci için: 1 msj çıkış + 1 msg giriş = 2. 2 istemci için: 2 msg çıkış, 2 msg giriş = 4. 3 istemci için: 3 msg çıkış, 3 msg giriş = 9 Ve böylece gider. Bunun gibi: bir durum msj gönder, sunucu bana ve diğer 2 istemciye (1 giriş, 3 çıkış) ve 3 istemcinin hepsi bunu yapıyor (1 giriş 9 çıkış). 3'ün sadece bir istemcisi için doğrusal görünse de, sistemin toplam verimi için bunu tüm istemcilerle çarpmanız gerekir. Desync'e gelince, aynı fiziksel kutudaki işlemler bile durum mesajı oluşturulana ve gönderilene kadar senkronize değildir, bu sadece borunun nerede boşaldığı, yerel RAM veya net meselesidir.
Patrick Hughes

5

İlgi alanı filtrelemesi kullanın. Bir dünya 3 sunucuya bölünmüşse ve sunucu 1'deki alan sunucu 3 alanına yakınsa, varlıklarla ilgili bilgileri paylaşmalarının hiçbir nedeni yoktur.

Aynı şekilde, tek bir sunucuda istemcilere yalnızca ilgili bilgileri gönderin. A oyuncusu, B oyuncusundan haritanın tamamen karşı ucundaysa, B'ye A ile ilgili güncellemeler göndermek için sıfır neden yoktur veya bunun tersi de geçerlidir.

Sürekli bir dünyada birden çok sunucunuz olduğunda, sunucu 2'de kenar 1 yakınında, sunucu 1'deki varlıklara yakın varlıklarınız olur. Bir varlığın "yetkili" sunucusundan diğer sunucuya güncellemeler gönderebilirsiniz (uygun olduğunda) ve aynı şekilde iletileri uygun şekilde yetkili sunucuya iletin.

Evet, bu durumda, bir sunucu belirli varlıklar için biraz güncelliğini yitirir. Bunu çözmeye çalışmayın. Sadece onunla ilgilen. Varlıkların biraz güncel olmadığını varsayalım. Güncel bilgilere ihtiyaç duyan herhangi bir mantığı yalnızca varlıkların yetkili olarak sahip olduğu sunucuda yapın. Bir varlık bir başkasını etkilediğinde, bir mesaj gönderin ve işlenmeden ve görünümünüz güncellenmeden önce birden fazla oyun mantığı kenarı alabileceğini varsayın.

Bu tasarım aynı zamanda tek bir sunucunun işlenmesini çok daha kolay hale getirir. Hiçbir varlık doğrudan bir başkasını değiştirmemeli, yalnızca ileti göndermemelidir ve yerel sunucu başına / iş parçacığı başına proxy önbelleklerinin biraz güncel olmadığı varsayılmalıdır.

Örneğin, varlık A varlık B'ye saldırırsa, B'nin ömrünü kontrol etmeyin ve 0'a ulaşırsa bir ölüm mesajı göndermeyin. Sadece "hasarlı" bir mesaj gönderin, B için yetkili sunucunun işlemesini sağlayın ve ardından A varlığı bunu önemsiyorsa, daha sonra sunucu B tarafından gönderilen "varlık-öldü" iletisi.

Aynı şey büyük, ölçeklenebilir oyun dışı uygulamalar için de geçerlidir. Merkezi bir veritabanı, sihirli bir anında paylaşım teknolojisi değildir. Yüksek verimi korumak için iki sunucunun toplu olarak mesajlarla eşzamansız olarak iletişim kurması gerekir. Bu nedenle AMPQ ve benzeri teknolojilerin popülaritesi. Veritabanları, kendileri senkronizasyon veya iletişim amaçlı oldukları için değil, iletişim için kullanılmalarına olanak tanıyan depolama ve destek senkronizasyonunu zorunlu kılar.


Teşekkürler, bu kalan şüphelerimin çoğunu sonlandırdı. Ayrıca bana sunucuları alanlar tarafından değil, oyuncular tarafından ayırma fikrini verdiniz - bu daha pürüzsüz görünecekti. Her sunucu x oyuncuyla ilgilenir. Bunu gerçekten beğendim! Bu kullanılıyor mu? Ve ayrıca, sadece bir şey daha var. Yukarıda sorduğum gibi, yeni bir NoSQL veritabanı olan Couchbase'i öğrendim. Çok yüksek yazma / okuma hızları dışında CouchDB gibi olması gerekiyordu: saniyede 200 bin güncelleme! Belki de bu aslında böyle bir "gerçek zamanlı paylaşılan dünya modeli" olarak işe yarayabilir ya da henüz işe yaramayabilir mi?
MaiaVictor

Bu teknik vahşi sunucuların olağan kaba "parçalama" yanı sıra vahşi kullanılırsa hiçbir fikrim yok. Sadece oyuncular ve coğrafi alan tarafından yapmak, her sunucunun farklı alanlarda çok sayıda varlığın farkında olması, sunucu yükünü arttırması ve sunucu içi iletişimi büyük ölçüde artırması gerektiği anlamına gelir. Bölgeye göre yapılması, sunucunuzun kalabalık alanlara aşırı yüklenebileceği anlamına gelir (ancak bu durumda alanları dinamik olarak bölebilir ve birleştirebilirsiniz), ancak her sunucunun takip etmek için daha küçük bir ilgili oyuncu olmayan varlık ve geometri kümesine sahip olduğu anlamına gelir. .
Sean Middleditch

@Dokkat: Her sunucunun oyun dünyasının belirli bir bölümündeki oyuncuları ele aldığı, ancak çok uzak durduklarında oyuncuları şeffaf bir şekilde başka bir sunucuya teslim ettikleri bir tür "yumuşak alanlara" sahip olmak mümkün olabilir. orijinal sunucu bölgesi. Sadece aktarmanın oyuncuların gerçekten fark etmeyecek kadar pürüzsüz olduğundan emin olmanız gerekir. Sadece bir bölge sınırında olsalar bile, etkileşimde bulunan oyuncu kümelerini aynı sunucuda tutmak için bazı süslü uyarlanabilir teknikler kullanmaya çalışabilirsiniz.
Ilmari Karonen

3

Muhtemelen ilgilenen edilecektir Gamasutra bu yazıda , Eve Online geliştiriciler bu başarıyla bir SQL veritabanında ... 400 000 aktif oyuncu ile bir oyun çalıştırmak için nasıl mümkün tartışır.


2

Veritabanını, her şey hakkında her şeyi her zaman saklayan bir tür gerçek zamanlı paylaşılan dünya modeli olarak düşünmeyin - fark ettiğiniz gibi, muhtemelen işe yaramaz.

Bunun yerine, veritabanına otomatik olarak güncellenen bir kaydetme dosyası gibi davranın: veritabanını yalnızca arada bir güncellersiniz, örneğin oyuncular oturum açtığında veya oturumu kapattığında veya bir bölgeden diğerine geçtiğinde veya istemediğiniz önemli bir şey olduğunda sunucu çökmesi durumunda kaybolur.

Gerçek zamanlı dünya durumu, oyun sunucunuz tarafından orijinal örneğinizde olduğu gibi bellekte tutulmalıdır. Şimdi yatay ölçeklemenin püf noktası, her sunucunun her an her şeyi bilmesi gerekmemesidir . Örneğin, A oyuncusu A sunucusundaki A bölgesinde oynuyorsa, B sunucusu çalışan bölgesi B'nin genellikle A oyuncunun sırt çantasında ne olduğunu bilmesine gerek yoktur - ve eğer bunu bir nedenle bilmeniz gerekiyorsa (örneğin, B bölgesindeki oyuncu B, A'ya bir tür uzaktan casusluk atışı verdiğinden) sadece diğer sunucudan bu bilgiyi isteyebilir .

Bu, sunuculara net sorumluluklar atamanızı gerektirir, böylece B sunucusu A oyuncusunun sırt çantası hakkında bilgi almak istediğinde, hangi sunucunun bu konuda yetkili bilgilere sahip olduğunu bilecektir. Muhtemelen bir çeşit güncelleme abonelik mekanizması eklemek isteyeceksiniz, böylece sunucu B sadece sunucu A'ya " A oyuncusunu casusluk yapan birisine sahibim, aksi halde söyleyene kadar yaptıkları her şey hakkında beni bilgilendirin. " ayrıca, oyuncuların nerede olurlarsa olsunlar bilmeleri gerekebilecek önemli küresel olaylar için bir tür küresel yayın sistemi eklemek istemektedir; Tabii ki, bu tür olaylar da veritabanına kaydedilmelidir, ancak bunların tüm sunuculara aktif olarak yayınlanması, sunucuların güncellemeler için veritabanını sorgulamaya devam etmeleri gerekmeyeceği anlamına gelir.


Müthiş cevap! Tam olarak sorduğum şey buydu, teşekkürler. Yani belki de anahtar, mantığı açık bellekte tutarak sunucuyu alanlara bölmektir. Yine de ekleyebilir miyim: Yeni bir NoSQL veritabanı, Couchbase hakkında yeni bilgi edindim. Çok yüksek yazma / okuma hızları dışında CouchDB gibi olması gerekiyordu: saniyede 200 bin güncelleme! Belki de bu aslında böyle bir "gerçek zamanlı paylaşılan dünya modeli" olarak işe yarayabilir ya da henüz işe yaramayabilir mi?
MaiaVictor

@ Dokkat hayır, olmayacak. Kanepe temeli sihir değildir.
Philipp

2

Diğer yanıtlar, veritabanının nasıl kullanılacağına ve iletişim için bir veritabanı kullanılmayacağına dikkat çekerek iyi bir iş çıkardı. Bakabileceğiniz bir diğer özellik, güncellemelerinizin bilgilerin diğer varlıklara nasıl iletilmesi gerektiğine göre sınıflandırılmasıdır. Sunucularla iletişim kurmak yerine, mesajınızı dağıtabilir ve varlıklar arasındaki güncellemeleri iletmek için pubsub mekanizmalarını kullanabilirsiniz. Örneğin, size yakın olan kişilere bağlı olarak konumu farklı şekilde ele alabilirsiniz:

  • R yarıçapı içinde hassas, gerçek zamanlı konum yararlı olabilir
  • 2 * R yarıçapında daha az kesin, daha az konum güncellemeleri yararlı olabilir
  • 2 * R yarıçapının ötesinde konum bilgisi gerekli olmayabilir

2 * R yarıçapındaki varlıkları periyodik olarak tarayarak (veya bir varlığın güncelleme hızına ve maksimum hızına bağlı olarak bunların birkaç katına) ve varlığı diğer varlığın kesin veya kesin olmayan konum feed'ine abone olarak bir varlık için konum bilgilerini iletebilirsiniz.

Farklı bilgi türleri için farklı stratejilere sahip olabilir, ortak şeyleri aynı mesaj kuyruklarında gruplandırabilir veya farklı varlıklara gitmesi gereken mesajlar için farklı sıralara sahip olabilirsiniz (veya bunları yalnızca en geniş varlık grubuna gönderebilir ve iletiler atılırsa) yararlı olmaz).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.