unucudaki "Lag" Sorununu Tarihe Gömen Optimizasyon Teknikleri
(C++ ve Database Ayarları İle Performans Artışı)Merhaba arkadaşlar,
Bir sunucu kurdunuz, en güzel sistemleri eklediniz, reklamınızı yaptınız ve o beklediğiniz an geldi: Sunucunuz oyuncularla dolup taşıyor. Ama sonra o korkulu rüya başlar, genel sohbetten tek bir kelime yükselir: "LAG VAR!"
Bu üç kelime, en harika projeyi bile yavaş yavaş ölüme götüren zehirdir. Çünkü kimse, karakterinin saniyeler sonra hareket ettiği, skillerinin havada asılı kaldığı bir oyunda oynamak istemez.
Bu rehberde, o zehrin panzehirini konuşacağız. Sunucunuzun motorunu, yani C++ kaynak kodlarını ve hafızasını, yani Database'i (MySQL) nasıl daha verimli hale getirebileceğimizi, tecrübeyle sabit olmuş en temel ve en etkili yöntemlerle anlatacağım.
1. Motor Odası: C++ Kaynak Kod Optimizasyonu
Lag'in en büyük kaynaklarından biri, oyunun ana mantığının işlendiği game dosyasının verimsiz çalışmasıdır. Bir işlemi yapması gerekenden 10 kat daha uzun yoldan yapıyorsa, oyuncu sayısı arttıkça bu yavaşlık katlanarak artar.* Sorun: Gereksiz Yük ve Sürekli Tekrarlanan SorgularTecrübeyle sabittir ki, en büyük yavaşlık, anlık olarak sürekli tekrarlanan ve aslında gereği olmayan işlemlerden kaynaklanır.
* Örnek: Oyuncunun lonca ismini göstermek için, her seferinde veritabanına SELECT guild_name FROM guild_member WHERE pid = X sorgusu gönderen bir kod düşünün. Ekranda 100 oyuncu varsa, saniyede yüzlerce kez aynı sorgular veritabanına yığılır. Bu, bir kütüphaneciye her saniye aynı kitabı sormak gibidir.
* Çözüm: Önbellekleme (Caching): Doğrusu şudur: Oyuncu oyuna girdiğinde, lonca bilgisi bir kere veritabanından okunur ve oyuncunun karakter verilerinin tutulduğu objenin içine yazılır. Loncası değişmediği sürece, o bilgi hep oradan, yani hafızadan, ışık hızıyla okunur. Veritabanı hiç yorulmaz. Bu mantığı, sıkça kullanılan ama nadiren değişen tüm veriler için (seviye, statü, grup bilgileri vb.) uygulamalısınız.
* Sorun: Verimsiz Döngüler (Brute-force Döngüler) Bir oyuncuyu bulmak için sunucudaki bütün oyuncuları tek tek tarayan bir fonksiyon, oyuncu sayısı 50 iken hızlı çalışır. Ama 500 oyuncu olduğunda, o fonksiyon sunucunuza kalp krizi geçirtir.
* Örnek: find_pc_by_name("KarakterAdı") gibi bir fonksiyon, eğer içeride tüm oyuncu listesini baştan sona dönen bir for döngüsü kullanıyorsa, bu bir felakettir.
* Çözüm: Haritalama (Mapping): Oyuncuları bir liste (list) veya vektör (vector) yerine, bir harita (map) içinde tutmak gerekir. std::map<std::string, LPCHARACTER> gibi bir yapı, bir oyuncuyu isminden aradığınızda, onu milyonlarca oyuncu içinden bile tek bir adımda bulmanızı sağlar. Tıpkı bir sözlükten kelime aramak gibi. Bu, sunucu kodlarındaki en temel optimizasyon kurallarından biridir.
2. Arşiv Odası: Database (MySQL) Optimizasyonu
Eğer kodlarınız temizse ama hala yavaşlık varsa, suçlu büyük ihtimalle arşiv odanız, yani veritabanınızdır.* Sorun: İndekssiz (Index) TablolarBu, veritabanı yavaşlığının %90 sebebidir. İndeks, bir tablodaki veriyi çok hızlı bulmanızı sağlayan bir fihristtir. Eğer bir tabloda fihrist yoksa, MySQL aradığı tek bir kaydı bulmak için milyonlarca satırı tek tek okumak zorunda kalır.
* Örnek: player.player tablosunda name (karakter adı) sütununda veya account.account tablosunda login sütununda indeks yoksa, her oyuncu girişi veya karakter arama işlemi bir eziyete dönüşür.
* Çözüm: Doğru Sütunlara İndeks Eklemek: Navicat veya benzeri bir programla tablolarınıza girin ve sıkça arama yaptığınız (WHERE koşulunda kullandığınız) tüm sütunlara indeks ekleyin. Özellikle id, name, login, owner_id, vnum gibi sütunlar mutlaka indeksli olmalıdır. Bu, sunucu ve site hızınızı 100 kat artırabilecek sihirli bir dokunuştur.
* Sorun: Verimsiz SorgularBazen indeks olsa bile, sorgunun kendisi kötü yazılmıştır.
* Örnek: Bir oyuncunun sadece envanterini görmek için SELECT * FROM item gibi bir sorgu çekmek, gereksiz yere onlarca sütunu ve tonlarca veriyi meşgul eder.
* Çözüm: Akıllı Sorgular Yazmak: Sadece ihtiyacınız olan sütunları seçin (SELECT vnum, count FROM item). MySQL'in EXPLAIN komutunu kullanarak sorgularınızın ne kadar verimli çalıştığını analiz edin. Gereksiz JOIN'lerden kaçının veya tam tersi, birden çok sorgu göndermek yerine tek bir akıllı JOIN ile işinizi halledin.
* Sorun: Yanlış Veritabanı MotoruHala MyISAM motorunu kullanan tablolarınız varsa, büyük bir hata yapıyorsunuz. MyISAM eski bir motordur, yoğun işlemlerde tablonun kilitlenmesine neden olur ve veri bütünlüğünü garanti etmez.
* Çözüm: InnoDB'ye Geçiş: Tüm tablolarınızın motorunu InnoDB olarak değiştirin. InnoDB, modern, daha hızlı ve çok daha güvenli bir motordur. Bu değişiklik, özellikle çok sayıda oyuncunun aynı anda veritabanına yazdığı durumlarda sunucunuza nefes aldırır.
Unutmayın arkadaşlar, optimizasyon bir kerelik bir iş değildir. Sürekli bir gözlem, analiz ve iyileştirme sürecidir. Ama bu rehberde anlattığım temel noktaları hallettiğinizde, sunucunuzdaki "lag" kelimesinin tarihe karıştığını ve oyuncularınızın size teşekkür ettiğini göreceksiniz.