aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Oyun Sunucusu

Sunucu Ölçeklendirme: Yatay mı Dikey mi?

Bir oyun sunucusu büyümeye başladığında ilk somut karar genellikle sunucu ölçeklendirme stratejisidir: aynı makineyi büyütmek mi (dikey), yoksa yük dağıtarak makine sayısını artırmak mı (yatay)? İkisi de geçerli yollardır, ama hangisinin sana uyacağı oyunun mimarisine, oyuncu sayısına ve darboğazın gerçekte nerede olduğuna bağlıdır. Bu yazıda iki yaklaşımı pratik ve teknik açıdan karşılaştırıyoruz.

Dikey ölçekleme: daha güçlü tek makine

Dikey ölçekleme (scale up), mevcut sunucuya daha fazla CPU çekirdeği, daha fazla RAM veya daha hızlı disk eklemek demektir. En büyük avantajı sadeliktir: kod tarafında hiçbir şey değişmez, dağıtık sistemlerin karmaşıklığıyla uğraşmazsın. Tek bir process, tek bir veritabanı, tek bir oyun dünyası state'i bellekte tutulur ve her şey aynı yerde olduğu için gecikme düşüktür.

Metin2, Tibia ya da benzeri klasik MMO mimarileri buna iyi örnektir: oyun mantığının çoğu tek bir game process içinde, paylaşılan bellekte çalışır. Böyle bir sistemde 200 oyuncudan 800 oyuncuya çıkmak çoğu zaman daha hızlı bir CPU ve daha çok RAM ile çözülür. Bulut sağlayıcılarda bu, birkaç dakikada bir instance'ı daha büyük bir boyuta taşımak kadar kolaydır.

Ama dikey ölçeklemenin sert bir tavanı vardır:

  • Fiziksel sınır: En büyük makineyi de seçsen, bir noktada eklenecek çekirdek kalmaz.
  • Tek hata noktası: O makine çökerse tüm oyun çöker. Yedeklilik yoktur.
  • Doğrusal olmayan maliyet: Üst segment donanım, çekirdek başına orantısız biçimde pahalanır.
  • Tek çekirdek darboğazı: Oyun döngün tek thread'de çalışıyorsa, 32 çekirdekli makine bile o tek thread'in hızıyla sınırlıdır.

Yatay ölçekleme: daha fazla makine

Yatay ölçekleme (scale out), yükü birden çok sunucuya dağıtmaktır. Oyunlarda bu nadiren "aynı dünyayı iki makineye böl" şeklinde olur; çünkü oyun state'i paylaşmak zordur. Pratikte yatay ölçekleme genellikle şu desenlerden biriyle gelir:

  • Sharding: Her makine ayrı bir dünya/realm/oda barındırır. Oyuncular shard'lara bölünür; aralarında doğrudan etkileşim olmaz.
  • Servis ayrıştırma: Auth, sohbet, eşleştirme (matchmaking), ödeme gibi parçalar ayrı servislere taşınır ve bağımsız ölçeklenir.
  • Maç bazlı sunucular: FPS/MOBA tarzı oyunlarda her maç kısa ömürlü bir sunucu instance'ında çalışır; bir orkestratör boş sunucuları doldurur.

Yatay yaklaşımın gücü esnekliktir: yük arttığında makine eklersin, azaldığında kaldırırsın. Tek bir makinenin çökmesi tüm sistemi düşürmez. Buna karşılık dağıtık olmanın bedeli vardır: durum paylaşımı, servisler arası iletişim, tutarlılık ve dağıtım karmaşıklığı.

Asıl soru: darboğaz nerede?

Ölçekleme kararını duygusal değil ölçümsel vermelisin. Önce gerçek darboğazı bul. Linux'ta hızlı bir bakış için:

# Genel yük ve çekirdek başına CPU
htop

# Tek tek çekirdeklerin doluluğu (tek-thread darboğazını görmek için)
mpstat -P ALL 1

# Disk I/O baskısı
iostat -x 1

# Ağ bağlantı sayısı ve durumları
ss -s

Bu çıktılar yön verir. Eğer tek bir çekirdek sürekli %100 ama diğerleri boşsa, sorun paralelleşmeyen oyun döngündedir; daha fazla makine eklemek bunu çözmez, daha hızlı CPU ya da kod tarafında thread ayrımı gerekir. Eğer tüm çekirdekler doluysa, dikey ölçekleme bir süre işe yarar. Eğer darboğaz veritabanı ise, ne yatay ne dikey app ölçeklemesi yeter; önce sorguları ve indeksleri düzeltmek gerekir.

Çoğu zaman doğru cevap: önce dikey, sonra ayrıştır

Gerçekçi bir büyüme yolu şöyle ilerler. Başlangıçta tek bir iyi yapılandırılmış makine kullan ve dikey büyü; bu en ucuz ve en hızlı yoldur. Bu sırada en kolay yatay adımı at: veritabanını ayrı bir makineye taşı. Oyun process'i ile MySQL'i ayırmak çoğu zaman tek başına büyük rahatlama sağlar, çünkü ikisi aynı CPU ve diski yormaz.

Sonraki adım, durumsuz (stateless) parçaları ayırmaktır: sohbet, web API, eşleştirme. Bunlar arkasına bir yük dengeleyici (örneğin nginx veya HAProxy) koyarak kolayca yatay ölçeklenir. Asıl oyun dünyasını ise mümkün olduğunca geç böl; sharding genellikle en zor parçadır ve ancak gerçekten gerektiğinde yapılmalıdır.

# nginx ile durumsuz API servislerini dengeleme örneği
upstream game_api {
    least_conn;
    server 10.0.0.11:8080;
    server 10.0.0.12:8080;
    server 10.0.0.13:8080;
}

server {
    listen 80;
    location /api/ {
        proxy_pass http://game_api;
    }
}

Maliyet ve operasyon farkı

Dikey ölçekleme operasyonel olarak ucuzdur: yönetilecek tek makine, tek log akışı, tek deploy. Ama donanım sınırına dayandığında maliyet uçar ve esneklik kalmaz. Yatay ölçekleme donanım başına daha verimli olabilir ama ekip maliyeti getirir: izleme, servis keşfi, dağıtık loglar, daha karmaşık dağıtım. Küçük bir proje için erken yatay ölçekleme çoğu zaman gereksiz mühendisliktir.

  • Az oyuncu, tek dünya: Dikey ölçekle, DB'yi ayır.
  • Çok realm/oda: Realm bazlı sharding ile yatay büyü.
  • Maç bazlı oyun: Orkestratörle dinamik sunucu havuzu.
  • Tek-thread darboğazı: Önce kodu profil et; donanım çözmez.

Sık Sorulan Sorular

Önce hangisini denemeliyim, yatay mı dikey mi?

Neredeyse her zaman dikey. Daha büyük bir makineye geçmek dakikalar sürer ve kod değişmez. Yatay ölçeklemeyi ancak donanım tavanına yaklaştığında ya da yedeklilik gerçekten kritik olduğunda devreye al.

Tek bir oyun dünyasını iki makineye bölebilir miyim?

Genelde hayır, en azından kolay değil. Aynı dünyayı paylaşmak için durumun makineler arasında tutarlı tutulması gerekir ki bu çok zordur. Onun yerine ayrı dünyalar (shard) ya da servis ayrıştırması tercih edilir.

Veritabanı darboğazını ölçeklemeyle çözer miyim?

Önce sorguları ve indeksleri düzelt. Yavaş bir sorgu, makine eklemekle hızlanmaz. İndeksler doğruysa, okuma replikaları ya da ayrı bir DB sunucusu gibi adımlar anlam kazanır.

Sunucunu büyütmeden önce darboğazı doğru teşhis etmek istiyorsan, oyun mimarini birlikte inceleyip sana en uygun ölçekleme yolunu çıkarabilirim. Benimle iletişime geç ve projeni konuşalım.

Bu kategorideki tüm yazılar →

Devamı için