Her geçen gün daha çok verinin saklandığı bir dünyada yaşıyoruz. Bugün herhangi bir veritabanına dokunmadan yazılım geliştirmek zor. Ne kadar iyi kod yazarsak yazalım kullandığımız veritabanlarının nasıl çalıştığını bilmiyorsak eninde sonunda düşük performanslı yazılımlar üretmemiz kaçınılmaz. Neyse ki veritabanları anlaması zor kara kutular değiller. Sırasıyla yazılım, donanım ve veritabanı katmanlarında birkaç noktaya dikkat ederek binlerce kata varan performans artışları elde etmek mümkün.
Yazılım Katmanı: İndeksler ve İşlemler
En kolay performans artışını sağlayabileceğimiz yer yazılım kodunun kendisi. Sık yapılan veritabanı sorguları, tablolardaki indekslerini kullanıyor mu kontrol etmek çok ciddi performans artışlarına neden olabilir. Yazılım geliştirirken genelde az miktarda test verisi kullanıldığı için sorgular ne kadar verimsiz olursa olsun dikkatten kaçabilir. Ta ki canlı ortamdaki veri sayısı kritik eşiği aşıp uygulama ekranları açılmamaya başlayınca kadar.
Sorguların indeks kullanmamasının iki nedeni olabilir. Ya sorgunun ihtiyaç duyduğu indeks hiç yoktur, ya da sorgunun yapısı varolan indeksleri kullanmaya uygun değildir. Her iki durum da tek bir kayıt için bile veritabanı sunucusunun milyonlarca ve hatta milyarlarca kaydı teker teker taramasına neden olabilir.
Hemen tüm veritabanları bir sorgunun indeks kullanıp kullanmadığını gösterebilir. Gerekli indeksleri eklemek veya indeksler varsa sorguları o indeksleri kullanacak şekilde değiştirmek çoğu zaman donanım ve veritabanı katmanlarına dokunmaya gerek kalmadan performans sorunlarını çözmede tek başına yeterli olabilir.
Eğer indekslerde bir sorun göremiyorsak ve işlem (transaction) destekleyen bir veritabanı kullanıyorsak (hemen tüm ilişkisel SQL veritabanları gibi) uzun süre çalışan işlem blokları var mı bakmakta yarar var. Her işlem bloğu içindeki sorgular sunucudaki diğer sorgulardan izole çalışabilir ve bir işlemde çalışan sorguların yaptığı değişikliklerin tümü istenirse tek bir komutla geri alınabilir (rollback). Bu esneklik güzel olsa da veritabanı sunucusu her bir işlem bloğunda yapılan değişiklikleri takip etmek zorundadır ve bir işlem ne kadar uzun sürerse takip edilmesi gereken değişiklik miktarı da o kadar artabilir. Bu yüzden işlemleri mümkün olduğunca kısa tutmakta yarar var.
Kısa işlemler iyi dediysek de sürekli olarak çok miktarda veri yazıyorsak, o verileri teker teker kısa işlem bloklarında yazmak yerine gruplayıp tek bir işlem bloğunda yazmak indekslerin her yazmada değil de tek seferde güncellenmesini sağlayacağından çok daha verimli olacaktır.
Özetlemek gerekirse işlemleri kısa tutmak iyidir; ama çok fazla veri yazarken de verileri ayrı işlem bloklarında yazmak yerine gruplayıp tek bir işlem bloğunda yazmak tercih edilmelidir.
Eğer yazılım katmanında herşey düzgün gözüküyorsa ve performans yine de yetersizse diğer katmanlara bakma zamanı gelmiştir.
Donanım Katmanı: RAM, Disk, Ağ, İşlemci Dörtlüsü
Bir veritabanı sunucusu için donanımsal olarak en önemli şey verileri saklamak için kullanacağı ortamın ne kadar hızlı erişilebildiğidir ve şu an için RAM’den daha hızlı bir saklama ortamı yok. Eğer bir veritabanındaki tüm veriler RAM’e sığabiliyorsa sorgular mümkün olan en hızlı şekilde çalıştırılabilir.
Her şeyi RAM’e sığdırmak her zaman mümkün olmadığından ikinci öncelikli ortam disktir. Mümkünse SSD disk tercih edilmeli ve hatta performans kritikse birden çok SSD disk RAID ile birleştirilip kullanılmalıdır.
RAM, ne yaparsak yapalım, SSD disklerden ortalamada en az 10 kat hızlı olacağından sunucuda mümkün olduğunca çok RAM bulunmalıdır. Eğer sunucu üzerinde yüksek disk erişimi görüyorsak ve işlemciler iş yapmak yerine zamanlarının çoğunu diski beklemekle geçiriyorlarsa (I/O wait), RAM miktarı yeterli değil demektir.
Genellikle uygulama ve veritabanı sunucuları ayrı sunucularda bulunduğundan veritabanı sunucusu ne kadar yüksek miktarda veri işleyebilir olursa olsun sunucular arasındaki ağ bağlantısı zayıf halkayı oluşturacaktır. O yüzden ağ bağlantısının hızının yüksek olmasına dikkat edilmelidir.
Son olarak da işlemciye değinelim. Veritabanı sunucularında işlemci çekirdek sayılarının çok ve hızlı olması uygulama sunucularının aksine çok önemli değildir; ancak işlemci üzerindeki ortalama yükün %50'yi aşmaması önemlidir. Bu sınır düşük gibi gözükebilir; ama yoğun zamanlarda anlık sorgu ihtiyaçlarını karşılayabilmek için yeterince boşta çekirdek olmalıdır. Aksi taktirde veritabanı sunucusu geride kalmaya başlayabilir, bekleyen sorgular yığılabilir ve sonunda yüksek işlemci kullanımı yüzünden sunucu çökebilir.
Veritabanı Katmanı: Ayarlar ve Replikasyon
Veritabanı yazılımları, pek çok diğer karmaşık yazılım gibi, en yüksek performansta çalışmak için doğru ayarlanmalıdır. Varsayılan ayarları değiştirmek çoğunlukla gereklidir. Her veritabanı sunucusunun ayarları farklı olduğundan hepsine değinmek mümkün değil; ama en azından RAM, önbellek kullanımı ve transaction’larla ilgili ayarların büyük ölçüde doğru olduğuna emin olunmalıdır. PostgreSQL kullanıyorsanız şanlısınız. pgtune gerekli ayarları sizin için otomatik olarak üretebilir. MS SQL Server kullanıyorsanız özellikle işlem izolasyon seviyesinin doğru olması aynı anda çok okuma ve yazma yapan uygulamalar için önemlidir.
Veritabanı ayarlarından sonra performansı arttırmakta kullanılabilecek en önemli yöntem replikasyondur. Replikasyon ana veritabanı sunucusunun anlık olarak güncellenen sadece okunabilir kopyalarını tutan yedek sunucular oluşturmak için kullanılır.
Replikasyonun esas amacı ana sunucuda bir donanım sorunu oluşursa en az veri ve zaman kaybı ile yedek sunucu üzerinden devam edebilmektir. Diğer taraftan okuma sorguları, uygulama tarafından replika sunucular üzerinde paylaştırılabileceğinden okuma performansı replika sunucusu sayısıyla orantılı artabilir. Tabi, replikaların ana sunucudan çok kısa da olsa geride kalabileceğini akılda tutup her zaman doğru olması gereken sorguları replikalardan yapmamalıyız.
Son olarak replikaların bir diğer yararı da veritabanı yedeklerinin ana sunucu üzerinden değil de replikalardan bir tanesinden yapılabilir olması. Böylece yedek alma aşamasında ana sunucu üzerinde bir performans kaybı yaşanmaz.
Hiçbir Şey İşe Yaramazsa
Yukarıda bahsedilen noktaların hiçbirinde bir sorun yoksa ve performans yine de yetersizse ayrı bir önbellek kullanma zamanı gelmiştir. Çok zaman alan sorguları tekrar tekrar yapmak yerine Redis veya benzeri bir önbellek çözümü kullanarak sorguların sonuçları önbellekte saklanabilir. Böylece veritabanı sunucusu üzerindeki yük azaltılıp performans arttırılabilir.
En Son Çare
Önbellek kullanımı da işe yaramadıysa belki de uygulamamızın ihtiyaçlarına uygun olmayan bir veritabanı yazılımı kullanıyoruzdur. Diğer veritabanı yazılımlarına bakma zamanı gelmiştir :)