Gerçek zamanlı oyunlar için en iyi sunucu mimarisi nedir?


10

Binlerce oyuncuyu gerçek zamanlı tutması gereken bir Gerçek Zamanlı oyun geliştiriyorum (FPS gibi. Max 1s lag). Bunun için en iyi altyapı ne olurdu?

Benim fikrim 2 sunucu kümesi kullanmaktı - biri Sunucu Sonu (tüm bilgi işlem tarafı için) ve diğeri Veritabanı sonu için, her bir kümeden bir yük dengeleyicisinin "sorumlu olduğu". Bir ana sunucu kullanıcılardan gelen istekleri alır ve kullanıcının çalışabileceği ilgili sunucunun IP adresini geri gönderir.

Veritabanı kümesi, veritabanları arasındaki tutarlılık için veritabanı çoğaltmasını kullanır.

Bir coğrafi yük dengeleyici de olmalıdır - bu nedenle her kullanıcıya en iyi yanıt için bölgesel yük dengeleyicisini atayacaktır.

Oyun için .NET + MSSQL kullanıyorum.

Teşekkürler!


2
"Altyapı" derken yazılım, donanım, hizmet mi demek istediniz, yoksa sadece mevcut planınızı olduğu gibi eleştirmemizi mi istediniz?
Tetrad

1
@Nate - çoğaltmak değil, ölçeklendirmeyi planlıyoruz - bu yüzden tamamen ölçeklenebilir olmalıdır.
roman

2
-1 çünkü teddziuba.com/2008/04/im-going-to-scale-my-foot-up-y.html - Herhangi bir kapasite gereksinimini karşılamıyorsunuz, oyunun parçalanmadığını, ancak bölgelerinin bölündüğünü söylüyorsunuz Ölçeklenebilirlik dahil olmak üzere performans optimizasyonlarının doğası belirli bilgiler gerektirir ve mutlak en iyi mimari yoktur.

1
Sorunuzu daha somut bir şeyle yeniden ifade ederdim. Gerçek, öznel olmayan bir şekilde 'en iyi' nedir? Yani ölçeklemesi en kolay, en kolay yönetilmesi, en kolay gitmesi, en hızlı veya ne?
Komünist Ördek

1
"En kolay" da özneldir. Kimin için en kolay, hangi zaman diliminde hangi kaynaklar verildi? Yığın Borsaları belirli sorularla en iyi şekilde çalışır - "Bu sunucuyu LINQ ve MSSQL kullanarak oluşturdum, ancak saniyede 70 işlemden sonra düştü, işte çalışma süremin% 73'ünü oluşturan ilk iki işlemim, iş hacmimi nasıl artırmalıyım? "

Yanıtlar:


6

İhtiyaçlarınız hakkında daha fazla bilgi sahibi olmadan en iyi mimari yoktur, örn. karakterler arasındaki etkileşimler, ne kadar verinin kalıcı olacağı vb.

1 saniyelik gecikmeyle başa çıkabiliyorsanız, muhtemelen tek bir sunucuda 1000 oyuncuyu sorunsuz bir şekilde barındırabilirsiniz - ancak bu genellikle bir FPS fikriyle çelişir, çünkü bunlar genellikle çok daha düşük gecikme süresi gerektirir, örn. 100ms'den az. Ancak yüksek gecikme ile başa çıkabilen bir sistem, tutarlılığı oldukça önemsiz hale getiren mesaj geçişi ile her şeyi yapabilir. Mantık sağlamanız oldukça basittir, yani - kilitli nesne sisteminden ziyade mesaj tabanlı bir sisteme dönüştürdüğünüzde karmaşık mantık daha da kötüleşir - ancak hepsi uygulamanızın ihtiyaçlarına bağlıdır.

Benzer şekilde, çok fazla veriyi sürdürmüyorsanız, veritabanı makinesine hiç ihtiyacınız yoktur, ancak bunu bilmeden söylemek zor. Küçük miktarlarda veriyi sürdürüyorsanız ve belki de sadece bir turnuvanın veya bir şeyin sonunda yapıyorsanız, yine ayrı bir veritabanına ihtiyacınız yoktur, kesinlikle bir kümeye değil. Öte yandan, çok fazla ısrar etmiyorsanız, ancak çok fazla okuyorsanız, çoğaltılmış veritabanlarının size yardımcı olabileceği yer burasıdır - ancak aynı zamanda ilişkisel bir veritabanının ilk etapta probleminiz için en iyi eşleşme olmayabileceğini gösterir. Genellikle bellek içi bir önbellek daha iyi bir çözümdür. Benzer şekilde, karakterler arasında işlem tarzı etkileşim yoksa tutarlılık daha az önem kazanır. (Ve bu tür işlemlerden sadece birkaçı varsa, bunları özel bir dava haline getirebilirsiniz.)

Aslında, sadece büyük sistemlerde yapılan bir şey olduğu için bir RDBMS'yi benimsemeye dikkat edin. Ben şahsen onları çevrimiçi oyunlarda kullanmayı onaylamama rağmen, tercih ettiğiniz veritabanını alıp sonra önbellek ve çoğaltma ile değiştirmeye çalışmak yerine, gereksinimlerinize bakmak ve kalıcılık stratejinizi anlamak en iyisidir. Uygulamanın. İhtiyacınız olan tek şeyin çevrimdışı raporlama özelliği olduğunu görebilirsiniz, bu durumda oyun kalıcılığı mekanizmanızdan başka bir yerde uzak bir RDBMS'ye giriş yapan bir arka plan işlemine sahip olmak en iyisidir.


4

Feragatname: Oyun programlama deneyimim istemci tarafı tek oyunculu oyunlara dayanıyor, ancak web uygulamalarında (özellikle Microsoft yığınında) bir arka planım var, bu yüzden bu cevapla geldiğim yer, çok şey olacağını hissediyorum uygulamak, ama gerçek bir oyun sunucusu gerçek test olmadan nasıl uygulanacağını söylemek zor, ama işte gidiyor. Şunu bilin: Bir oyun sunucusu kurmadım, sadece webapps.

İki (sunucu) katman yaklaşımı öneririm. Bir veritabanı katmanı ve bir "uygulama" katmanı; üçüncü (sunum) katmanı oyun istemcinizdir.

İlişkisel veritabanları, veri sorgulamada mükemmeldir ve veri yazmada iyi olur. Anahtar, veritabanı yazılarınızı kümenizin işleyebileceği yönetilebilir boyut yığınlarına serileştirmektir. SQL Server'ın daha gelişmiş sürümleri (Veri merkezi / Enterprise) kümelemeyi ve çoğaltmayı destekler. Nasıl çalıştığını görmek için küçük bir küme oluşturarak ve buna karşı bazı sorgular çalıştırarak başlardım.

Uygulama katmanında, "imar" veya benzeri bir şey yapıyorsanız, büyük olasılıkla herhangi bir küme ayarlamadan kurtulabilir ve her bölge için bir sunucu kurabilirsiniz. Bölgeleriniz büyürse, her bölge için bir küme oluşturabilirsiniz.

Uygulama katmanı -> veritabanı katmanından veri göndermek için bir serileştirme işlemi oluşturmak isteyeceksiniz. Anahtar, çoklu serileştirme seviyelerinin devam etmesidir. Bunun gibi bir şey :

  • Seviye 1: Her X saniyede bir DB'ye kaydedin, kritik veriler içerir:
    • Oyuncu Sağlığı
    • Oyuncu Eşyaları / Pikapları
  • 2. Seviye: Her 2X saniyede bir DB'ye kaydedin, orta düzey veriler içerir:
    • Oyuncu konumları
    • NPC konumları
  • Seviye 3: Mümkün olduğunca seyrek olarak diğer her şey

Bu, yazınızın tutarlı ve öngörülebilir olmasını sağlar, oyununuzun doğasına bağlı olarak, nadiren veritabanı yazımlarınız olabilir. Anahtar, uygulama sunucunuz çökerse, veritabanınızdaki durumdan tekrar çevrimiçi olmanız gerektiğini anlamaktır, böylece her 90 dakikada bir oyuncu envanterini serileştirmek oyuncuları rahatsız edebilir.

Verileri okumak için, uygulama katmanındaki belleğe mümkün olduğunca belleğe yüklemek ve ardından tüm kodunuzun bu bellek havuzunu kullandığından emin olmak istersiniz, arka planda bellek havuzunu veritabanıyla senkronize edebilirsiniz. Joe'nun işaret ettiği gibi, "gerçek zamanlı" işlemlere ihtiyaç duyduğunuz zamanlar olacaktır. Çoğu yazınızı serileştirerek, veritabanı sunucusunda / kümesinde yeterli donanım olduğunu varsayarak, gerektiğinde gerçek zamanlı işlemler yapmak için veritabanınızda yeterli G / Ç'ye sahip olmanız gerekir.


-1 çünkü sadece ACID attınız ve sadece veritabanını büyük bir veri deposu olarak kullanıyorsunuz. Bu iyi, Windows disk zamanlayıcısı hala bir performans kazancı olan yeterince crappy ve muhtemelen içindeki verilerle düzgün çevrimdışı metrikler yapabilirsiniz, ancak yine de ACID - yani bir veritabanı - oyundaki işlemleri yedekleyin, gerçek zamanda.

Seyrekken, bu son paragrafta doğru gidiyordum. Mümkün olan yerlerde IN-Memory ve gerektiğinde veritabanını kullandığınız bir melez, tavsiye ediyorum.
Nate

Sorun şu ki, başka bir veritabanı olan bellekte ne varsa, bunu nasıl uygulayacağınıza dair hiçbir yön vermediniz, ki bu gerçek zor bit.

Doğru, soru uygulama detaylarıyla değil, büyük resim mimarisiyle ilgiliydi.
Nate

Doğru, ama tüm orta katmanı dışarıda bıraktın. Gecikme süresi düşük bir RDB mi? ODB mi? Anahtar / değer deposu mu? DB yok ve ACID'den vazgeçmek mi? STM mi yoksa kilitleme mi? Adil olmak gerekirse, soruda çok fazla bilgi olmadığı için cevap vermek çok zordur, ancak mimari şemaya yapılan tüm bu cevap ortadaki büyük balonu bir "?" ve iki hizmet daha bağlayın, aslında ne "?" dır-dir.
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.