Skip to content

November 8, 2010

3

Veritabanı Ölçeklendirme Önerileri ve Kullanım Örnekleri

Merhaba arkadaşlar, bu yazımızda veritabanı (database) ölçeklendirmesi için kendi kullandığımız bir kaç yöntemi anlatmaya çalışacağız.

Neden Ölçeklendirme ?

Veritabanı ölçeklendirme gerekliliği yoğun istek alan veritabanı sunucu yüklerini paylaştırmak için kullanılabilecek maliyeti en düşük yöntemdir.

Nasıl Çalışır ?

Bizim anlatacağımız veritabanı ölçeklendirme sistemi yoğun istek alan veritabanı tablolarının sunucular üzerine paylaştırılması ise sağlanır.

Kısıtlamalar ?

Eğer kalıcı tablo verilerini (kısa süreli tutulmayan kayıtlar) ölçekleme yapıyorsak tablo üzerinde ki veri bütünlüğünü sağlamak için ekstra kod geliştirmeniz gerekebilir. Ancak verilerin yönetimi sunulmasından daha kolay olacağından çokta elzem bir durum değildir. Öneri olarak (kalıcı veriler için) periyodik data birleştirmesi yapabilir yada belirli bir gruba göre ölçekleme yaparak her bir tabloyu ayrı ayrı yönetebilirsiniz.

Örnek Senaryo 1 (max-db-rows)

Örnek bir senaryo ve kullanım örneği vermek için SameURL.com alt yapısında kullandığımız yönteme değinmek istiyoruz. Burada kullanıcıya referans dönülen id nin oluşturulması algoritmasına girmeyeceğiz. Siz isterseniz kullanıcıya integer da dönebilirsiniz ancak bununda dezavantajları vardır.

İstenilen: Kısaca sistemin çalışma yapısından bahsetmek isiyoruz. Sistem anasayfada kullanıcıdan aldığı URL yi alıyor veritabanına kaydedip kullanıcıya bir referans numarası veriyor. Daha sonra kullanıcı bu referans numarası ile istekte bulunduğunda kaydedilen URL ye gitmesi gerekiyor. Ayrıca bu kısa linke tıklayan herkesin loglarınıda tutmak gerekiyor. Yani siz SameURL.com adresine gidip https://blog.mustafakirimli.com/apache-mod_pagespeed-linux-uzerinde-kurulumu/626 URL sini yapıştırdığınızda http://sameurl.com/f6Ut8 gibi (her URL için ayrı id verilir) bir URL alırsınız. Buradaki f6Ut8 sayısı kullanıcıyı yukarıdaki gerçek URL ye yonlendirmesi gerekmektedir.

Çözüm: Bunun ilk ve en basit yontemi veritabanında bir tabloya f6Ut8 kodunu string olarak kaydetmek ve kullanıcı sorguladığında veritabanından çekip yönlendirmek olacaktır (ölçeklendirme olmadan).

Sorun: Kayıtlı URL sayısı milyonlara ulaştığında (iyi bir sistemin bu ve daha fazlasını göz önünde bulundurarak tasarlanması gerekmektedir) ve buna bağlı tıklama istatistiklerinin de ortalama yüz katına (URL başına ortalama tıklama sayısı 100) ulaştığında sistemin bu isteklere cevap verebilmesi, MyISAM kullanıyorsak tablo kilitlenmelerinin önüne geçilmesi, kaydedilecek veri daha da büyüdüğünde sunucunun yükü kaldırması gibi sorular.

Çözüm: SameURL.com ‘da bu sorunları yaşamamak için hemde paylaşımlı hostinglerde bile kodun rahatlıkla ölçeklenmiş halde çalışabilmesi için tablo verilerini 500 adet (birazda deneysel olması için) veritabanına dağıtmaya karar verdik. Her ne kadar paylaşımlı hostinglerde birbirinden farklı veritabanları oluşturduğunuzda aynı sunucuya düşme ihtimali olsada genellikle veritabanı disk limiti olduğundan bu limite takılmamış oluyorsunuz. Ayrıca çalıştığınız firma büyükse Grid Hosting (wiki en: Grid Computing) gibi teknolojiler kullanıldığından veritabanı sunucusu onlarca hatta yüzlerce sunucudan oluşabileceğinden aşırı yüklenme ihtimali çok düşüktür.

Şimdide bu tasarımı veritabanına uygulamak için geliştirdiğimiz algoritmadan bahsedelim. Biz her URL için kullanıcıya referans (kayıt id si) olarak 64 tabanında bir sayı ([a-zZ-A0-9_-] yani latin küçük harfler + latin büyük harfler + rakamlar + iki özel karakter) dönüyoruz. Bu referans numarasını (yukarıdaki örnekte bulunan f6Ut8 gibi) 10 tabanında sayıya çeviriyoruz. Çıkan sonucu veritabanı başına tutulacak maksimum sayıya bölüyoruz. Sonrasında da  sonucu aşağıya yuvarlıyoruz (Burada veritabanı kayıt sayısı limitini de 64 tabanında yazıp bölebilirsiniz ancak biz çevirmeyi uygun gördük). Ayrıca programlama dilinizin ve işletim sisteminizin desteklediği maksimum integer sayıyı göz önünde bulundurun. Mesela PHP 32 bit için bahsettiğimiz işlemi BC Math fonksiyonlarını kullandık. Aksi halde sayıyı cast ettiğinizde karşınıza hiçte hoşlanmayacağınız sonuçlar gelebilir.

Bu işlem veritabanına kısıtlama getiriyor. Zaten burada önerdiğimiz MySQL veritabanıda hiçbir konuda limitsiz değil. UNSIGNED INT kullanıyorsanız 2 milyar küsür BIGINT kullanıyorsanızda biraz daha fazla sayıyla çalışabilirsiniz ancak limit kabusunuz olmasın. Diskinizinde bir limiti olduğu unutmayın. Bu sebeple (en azından bizim yaşadığımız küçük tecrübelerde) limiti kafamıza takmayalım diyoruz. Bu yapıyla SameURL.com 1 milyar kayıt sayısına ulaştığında sistem çökecek gibi görünür. Bu limite dayandığında 500 adet daha db oluşturarak üst limiti rahatlıkla artırmış olursunuz.

Ayrıca db pozisyonunu ve referans numarasını belirleyen siz olduğunuzdan 501. veritabanının aranması söz konusu değildir. Yukarıda bahsettiğimiz işlemin tersini yapmak için yine 64 tabanında çok fazla uğraşmamak için 1 ile 500 arasında rand ile sayı oluşturup db pozisyonunu seçiyoruz. Daha sonra da ilgili veritabanında çalışabiliyoruz.

Örnek db pozisyonu bulma sonucu :
(f6Ut8)64 = (116.323.645)10
116.323.645 / 2.000.000 = 58.1618225
DB = 58

Çevirim işlemleriyle alakalı kaynak kodları daha sonra başka bir yazımızda yayınlamayı düşünüyoruz.

Kısıtlamalar:

  • Her veritabanına maksimum kayıt limit
  • Tüm veritabanlarında maksimum kayıt limiti (bunu yazıyoruz ancak sınırsız veritabanı zaten çok azdır hele de performans gerekiyorsa)

Şimdilik yazımızı burada bitiriyoruz. Yapacağımız araştırmalar sonucunda yeni algoritmalar bulduğumuzda yazıyı güncelleyeceğiz.

Toplam 3 Yorum Yorum Yaz
  1. engin
    Dec 20 2011

    çok güzel bir yazı. tam anlayamasam da, 5 – 6 kez daha okuyacağım 🙂

    Reply
  2. alper caner
    Jul 3 2012

    Çok güzel bir makale. Ölçeklendirme konusunda fikir sahibi olmak adına çok yararlı oldu. Tabloyu kendi kodlamamızla farklı dblerde tutmak hiç aklıma gelmemiştir. Sürekli clustering vb. gibi ölçeklendirme yöntemlerini öğrenmek gerektiğini düşünüyordum.

    Reply
  3. Kemal Ünal
    Sep 3 2012

    Süper bir makale olmuş. db pozisyonu bulma işlemi süper, ilham kaynağı oldu.

    Reply

Leave a Reply to engin

(gerekli)
(gerekli)