• 19-03-2020, 01:42:45
    #1
    Türkiye ve yurt dışında ağır yüklü (Günlük 500K+) web sitelerine ve sunucularına optimizasyon yapan bir kişi olarak (Bu bir reklam değildir tam tersi yararlanmanız içindir.) gördüğüm en büyük sorun; insanların database konusunda özellikle mysql bilgisiz olmaları ve optimizasyonları internette gördükleri paylaşılan onlarla alakası olmayan configurasyon dosyalarına göre yapmalarıdır.

    Bir kullanıcının yapacağı en büyük hata kendisine ait olmayan bir konfigurasyon dosyasını başka kişide iyi sonuc verdi diye yüklemesidir. Çünkü Mysql gibi veri tabanlarındaki konfigurasyon ayarları tamamen sizin sunucunuzun ram, işlemci ve yeterli hard disk miktanınıza göre yapılması gerekmektedir.

    Konuyu cok fala uzatmadan bir kaç püf noktayı önemli olan sizlere sunacak ve bunu baz alıp uyguladığınızda %500 den fazla olabilecek bir hızlandırma tekniğine sahip olacağınızı belirtmek isterim.

    Öncelikle artık teknolojide geliştiği için ve fiyatlar eskisine göre daha ucuz olduğu için yetersiz olarak sınıflandırılan sunucular pek piyasada kalmadı. Artık dedicated dediğimiz kişiye özgü tek kişi kullanımlık sunucular en kötü 16gb ram 8 vcpu ya sahip. Eğer ki bu tür bir sunucuya sahipseniz ve sunucuda barınan web sitesi sayısı hosting gibi şirketlerdeki gibi 50 den fazla değilse. (50 hoşgörülü bir rakam 1000 demek lazımdıda neyse) Query Cache yöntemi kullanmak zorunda değilsiniz.

    Query Cache dediğimiz olay mysql'de sorguları hard diskte yazıp bir daha cağrıldığında cache suresi bitmediyse direk hard diskten okuyan bir yöntemdir. Hard diskten veri okuma ve veri yazma olayı emin olun normal connection kurmaya göre ekstra daha yavaştır. Çünkü bu işlem anında mysql tablolarınızı lock edecek ve işlem sonlanana kadar gelen diğer query isteklerini wait statusunde bekletecektir.

    Bu bekletme işi ne kadar uzun surerse ve o sure zardında ne kadar fazla insert tipi query gelirse sırada bekleyen işlemler artacak ve kaçınılmaz cpu kullanımının %90lara vardığı load'ın ise %30 lara cıktığı bir kasma problemi oluşacaktır. Ve bu işlem katlanarak artacak mysql restart edilip bekleyen queryler temizlenene kadar da durmayacaktır.

    Peki çözüm nedir? Bu gibi az siteli sunucular query cache = 0 belirtilerek cache tutulmaması istenir. Genellikle türk kullanıcılar her web sitesini wordpress altyapısı olarak kullandığını varsayarsak. İlla bir cache sistemi kullanılmak isteniyorsa (kesinlikle öneriyorum) php versiyonunuza göre (php 7.1altı memcache, 7.1 ve üstü memcached) memcached sınıfındanyararlanıp wp queryleri memcache de tutabilirler ve günümüzün en çok kullanılan en profesyonel ve hızlı cache altyapısının memcached olduğunu unutmayın.

    Mangodb'de memcache yapısı default olarak kullanıldığı için mambodb kullananlar mysql yerine ekstra birşey yapmalarına gerek yoktur. Hatta bilgisi ve imkanı olanlar mysql yerine mambodb kullanmaları çok daha iyi olacaktır. Dünyanın en fazla veri ağına sahip olan yüklü web siteleri facebook gibi tamamen ram cache yontemine bağlı mambodb kullanmaktadır bunuda ekstra bilgi olarak geçelim.

    Gelelim illa query cache kullanmak isteyen kullanıcılara. Query cache eğer kullandığınız server side dilinde örneğin php hiç bir cache sistem kullanmıyorsanız kullanılabilecek bir yöntemdir.

    Bakın bir web sitesinde cache önem sıralaması şu şekildedir.

    1. Browser Cache -> Scriting Cache -> HTTPD Cache -> SQL Cache -> HDD Cache

    Yani bu ne anlama geliyor. Öncelikle eğer browser cache ayarlanmadıysa, üstüne php de de cache kullanmıyorsanız (memcache, xcache vs) bari httpd cache kullanılıyor mu diye bakalım (apache yada nginx cache) oda mı yok aman tanrım o zaman sql cache yapalım (query cache) odamı yok bariz hdd ye yazalım.

    Yani query cache en son bakılacak ve kullanılacak yöntemler arasında yer alır. Bir web sitesini ayakta tutacak ana cache browser cache ve php nin kullanacağı cache yöntemleridir. Vehatta yeni web teknolojisiyle workers dediğimiz tamamen local bilgisayarda cache tutmayı sağlayan sistemler vardır ve bunlar şuanda en cok performans sağlayan cache yöntemleridir. Sunucuya isteği göndermeden tamamen bağlantının localinde tuttuğu cache ile herşeyi halleder. Localin net bağlantısı olmasa bile web sitesize uygulamaymış gibi bağlanabilir bu sayede.

    Ama hala query cache kullandığınızı düşünürsek siz teknoloji bakımından workers'a göre taş devrinde olduğunuzu varsaymaz zorunda kalırız ve önce taş devrini atlatmak adına bililenmemiz gerekir.

    Madem bilgisiziz ve senelerdir kullandığımız yöntemi kullanıyorz o zaman nasıl en iyi hale getiriz diye düşüneceksek küçük bir hileden bahsedeceğim.

    Bu hile sunucunuzun sahip olduğu ram'in belirli bölünü hard disk gibi gösterip sunucuya yutturarak tüm query cache memory de tutmaktır. Çünkü ram'e yazılan veri hızı hard diske yazılan veri hızına göre 10.000 kat daha hızlıdır. Aynı şekilde veri okuma içinde geçerli.

    Ne yapıyoruz bunun için:

    Öncelikle sunucumuzun ram miktarınu öğreniyoruz. Diyelim ki 32 GB ram'e sahibiz o zaman bunun 16 gb'ını bu işlem için ayırabilirim olarak düşünmek mantıklı bir matematiksel işlemdir.

    Sunucularda mysql yine aynı isimli mysql user uzerinden işlem görür. Mysql user'ın pid ve uid değerlerini buluyoruz. Sunucumuza ssh ile root olarak bağlanıp aşağıda gördüğümüzü yazıyoruz.

    id mysql
    bunun karşılı olarak şu şekilde bir sonuc dönecektir.

    uid=27(mysql) gid=27(mysql) groups=27(mysql)
    Bu sonuctan uid, gid ve groups değerlerinin idsini kaydedelim. Daha sonra tamamen hesapladığımız ram miktarını aktaracağımız sahte bir tmp dizini yaratıyoruz. adı tmpfs olsun. Bunun için

    mkdir /var/tmpfs
    komutunu yazarak var bölümüne ekliyoruz. Daha sonra işletim sisteminin bağlı depolama birimlerini yöneten konfigurasyon dosyasını vim yada nano komutu ile editleyeceğiz.

    nano /etc/fstab
    ile dosyayı açarak aşağıda gördümüz satırı en sonra eklememiz lazım. ama aşağıdaki satırdaki uid ve gid değerleri yukarıda id mysql komutuyla aldığımız değerlerle birebir olacak. Bunu siz kendi sunucunuzdaki uid ve gid değerlerine göre değiştirmelisiniz.

    tmpfs /var/tmpfs tmpfs rw,uid=27,gid=27,size=16G,nr_inodes=10k,mode=0700 0 0
    Ramiz 32GB idi yarısını 16G olarak mysql uuidine yetkili tmp klasörü olarak belittik. Daha sonra dosyayı bu şekilde save edip son olarak restarta gerek olmadan yeni depolama arabirimini tanıması için aşağıdaki komutu giriyoruz.

    mount -a
    Artık sunucumuz sanki yeni bir depolama birimi takmışız gibi yeni bir bölüm tanıyacaktır. Ve bu bölüm aslında ram olacaktır ama sunucuyu hdd olarak kandırdığımız için ram değil bu birimi bir depolama birimi olarak görecektir.

    Son olarak mysql conf dosyamıza gidiyoruz

    nano /etc/my.cnf
    hemen [mysqld] bölümüne;

    tmpdir=/var/tmpfs
    tmp_table_size=2K
    Alanını ekliyoruz ve mysql sunucusuna restart atıyoruz. Bundan sonra cacheler ramde tutulacak ve hdd verilerine göre çok daha hızlı olacaktır.

    Bu arada küçük bir püf nokta vereyim.

    Lütfen tablo yapılarınızı MyIsam kullanmayınız. Sene 2020 MyIsam bundan 10 sene önce dandik sunucularda performanslı olabilirdi fakat mysql tablo yapısı her insert değer için tüm tabloyu lock edip beklemeye alır insert işlemi bitene kadar o yüzden bunun yerine async calışan ve lock etmeyen innodb kullanın.

    Tek sorgularda myisam'e göre 0.002 saniye yavaş olabilir fakat tüm işlemler baz alındığında 50 kat daha performans sağladığını göreceksiniz ve bu kanıtlanmış bir gerçektir.

    Saygılar.
  • 19-03-2020, 01:51:12
    #2
    Tam okumadım ama ilk bir kaç satırın kalite koktuğunu söylemekten kendimi alamadım. Teşekkürler.
  • 19-03-2020, 02:12:41
    #3
    Caesar adlı üyeden alıntı: mesajı görüntüle
    Türkiye ve yurt dışında ağır yüklü (Günlük 500K+) web sitelerine ve sunucularına optimizasyon yapan bir kişi olarak (Bu bir reklam değildir tam tersi yararlanmanız içindir.) gördüğüm en büyük sorun; insanların database konusunda özellikle mysql bilgisiz olmaları ve optimizasyonları internette gördükleri paylaşılan onlarla alakası olmayan configurasyon dosyalarına göre yapmalarıdır.

    Bir kullanıcının yapacağı en büyük hata kendisine ait olmayan bir konfigurasyon dosyasını başka kişide iyi sonuc verdi diye yüklemesidir. Çünkü Mysql gibi veri tabanlarındaki konfigurasyon ayarları tamamen sizin sunucunuzun ram, işlemci ve yeterli hard disk miktanınıza göre yapılması gerekmektedir.

    Konuyu cok fala uzatmadan bir kaç püf noktayı önemli olan sizlere sunacak ve bunu baz alıp uyguladığınızda %500 den fazla olabilecek bir hızlandırma tekniğine sahip olacağınızı belirtmek isterim.

    Öncelikle artık teknolojide geliştiği için ve fiyatlar eskisine göre daha ucuz olduğu için yetersiz olarak sınıflandırılan sunucular pek piyasada kalmadı. Artık dedicated dediğimiz kişiye özgü tek kişi kullanımlık sunucular en kötü 16gb ram 8 vcpu ya sahip. Eğer ki bu tür bir sunucuya sahipseniz ve sunucuda barınan web sitesi sayısı hosting gibi şirketlerdeki gibi 50 den fazla değilse. (50 hoşgörülü bir rakam 1000 demek lazımdıda neyse) Query Cache yöntemi kullanmak zorunda değilsiniz.

    Query Cache dediğimiz olay mysql'de sorguları hard diskte yazıp bir daha cağrıldığında cache suresi bitmediyse direk hard diskten okuyan bir yöntemdir. Hard diskten veri okuma ve veri yazma olayı emin olun normal connection kurmaya göre ekstra daha yavaştır. Çünkü bu işlem anında mysql tablolarınızı lock edecek ve işlem sonlanana kadar gelen diğer query isteklerini wait statusunde bekletecektir.

    Bu bekletme işi ne kadar uzun surerse ve o sure zardında ne kadar fazla insert tipi query gelirse sırada bekleyen işlemler artacak ve kaçınılmaz cpu kullanımının %90lara vardığı load'ın ise %30 lara cıktığı bir kasma problemi oluşacaktır. Ve bu işlem katlanarak artacak mysql restart edilip bekleyen queryler temizlenene kadar da durmayacaktır.

    Peki çözüm nedir? Bu gibi az siteli sunucular query cache = 0 belirtilerek cache tutulmaması istenir. Genellikle türk kullanıcılar her web sitesini wordpress altyapısı olarak kullandığını varsayarsak. İlla bir cache sistemi kullanılmak isteniyorsa (kesinlikle öneriyorum) php versiyonunuza göre (php 7.1altı memcache, 7.1 ve üstü memcached) memcached sınıfındanyararlanıp wp queryleri memcache de tutabilirler ve günümüzün en çok kullanılan en profesyonel ve hızlı cache altyapısının memcached olduğunu unutmayın.

    Mangodb'de memcache yapısı default olarak kullanıldığı için mambodb kullananlar mysql yerine ekstra birşey yapmalarına gerek yoktur. Hatta bilgisi ve imkanı olanlar mysql yerine mambodb kullanmaları çok daha iyi olacaktır. Dünyanın en fazla veri ağına sahip olan yüklü web siteleri facebook gibi tamamen ram cache yontemine bağlı mambodb kullanmaktadır bunuda ekstra bilgi olarak geçelim.

    Gelelim illa query cache kullanmak isteyen kullanıcılara. Query cache eğer kullandığınız server side dilinde örneğin php hiç bir cache sistem kullanmıyorsanız kullanılabilecek bir yöntemdir.

    Bakın bir web sitesinde cache önem sıralaması şu şekildedir.

    1. Browser Cache -> Scriting Cache -> HTTPD Cache -> SQL Cache -> HDD Cache

    Yani bu ne anlama geliyor. Öncelikle eğer browser cache ayarlanmadıysa, üstüne php de de cache kullanmıyorsanız (memcache, xcache vs) bari httpd cache kullanılıyor mu diye bakalım (apache yada nginx cache) oda mı yok aman tanrım o zaman sql cache yapalım (query cache) odamı yok bariz hdd ye yazalım.

    Yani query cache en son bakılacak ve kullanılacak yöntemler arasında yer alır. Bir web sitesini ayakta tutacak ana cache browser cache ve php nin kullanacağı cache yöntemleridir. Vehatta yeni web teknolojisiyle workers dediğimiz tamamen local bilgisayarda cache tutmayı sağlayan sistemler vardır ve bunlar şuanda en cok performans sağlayan cache yöntemleridir. Sunucuya isteği göndermeden tamamen bağlantının localinde tuttuğu cache ile herşeyi halleder. Localin net bağlantısı olmasa bile web sitesize uygulamaymış gibi bağlanabilir bu sayede.

    Ama hala query cache kullandığınızı düşünürsek siz teknoloji bakımından workers'a göre taş devrinde olduğunuzu varsaymaz zorunda kalırız ve önce taş devrini atlatmak adına bililenmemiz gerekir.

    Madem bilgisiziz ve senelerdir kullandığımız yöntemi kullanıyorz o zaman nasıl en iyi hale getiriz diye düşüneceksek küçük bir hileden bahsedeceğim.

    Bu hile sunucunuzun sahip olduğu ram'in belirli bölünü hard disk gibi gösterip sunucuya yutturarak tüm query cache memory de tutmaktır. Çünkü ram'e yazılan veri hızı hard diske yazılan veri hızına göre 10.000 kat daha hızlıdır. Aynı şekilde veri okuma içinde geçerli.

    Ne yapıyoruz bunun için:

    Öncelikle sunucumuzun ram miktarınu öğreniyoruz. Diyelim ki 32 GB ram'e sahibiz o zaman bunun 16 gb'ını bu işlem için ayırabilirim olarak düşünmek mantıklı bir matematiksel işlemdir.

    Sunucularda mysql yine aynı isimli mysql user uzerinden işlem görür. Mysql user'ın pid ve uid değerlerini buluyoruz. Sunucumuza ssh ile root olarak bağlanıp aşağıda gördüğümüzü yazıyoruz.

    id mysql
    bunun karşılı olarak şu şekilde bir sonuc dönecektir.

    uid=27(mysql) gid=27(mysql) groups=27(mysql)
    Bu sonuctan uid, gid ve groups değerlerinin idsini kaydedelim. Daha sonra tamamen hesapladığımız ram miktarını aktaracağımız sahte bir tmp dizini yaratıyoruz. adı tmpfs olsun. Bunun için

    mkdir /var/tmpfs
    komutunu yazarak var bölümüne ekliyoruz. Daha sonra işletim sisteminin bağlı depolama birimlerini yöneten konfigurasyon dosyasını vim yada nano komutu ile editleyeceğiz.

    nano /etc/fstab
    ile dosyayı açarak aşağıda gördümüz satırı en sonra eklememiz lazım. ama aşağıdaki satırdaki uid ve gid değerleri yukarıda id mysql komutuyla aldığımız değerlerle birebir olacak. Bunu siz kendi sunucunuzdaki uid ve gid değerlerine göre değiştirmelisiniz.

    tmpfs /var/tmpfs tmpfs rw,uid=27,gid=27,size=16G,nr_inodes=10k,mode=0700 0 0
    Ramiz 32GB idi yarısını 16G olarak mysql uuidine yetkili tmp klasörü olarak belittik. Daha sonra dosyayı bu şekilde save edip son olarak restarta gerek olmadan yeni depolama arabirimini tanıması için aşağıdaki komutu giriyoruz.

    mount -a
    Artık sunucumuz sanki yeni bir depolama birimi takmışız gibi yeni bir bölüm tanıyacaktır. Ve bu bölüm aslında ram olacaktır ama sunucuyu hdd olarak kandırdığımız için ram değil bu birimi bir depolama birimi olarak görecektir.

    Son olarak mysql conf dosyamıza gidiyoruz

    nano /etc/my.cnf
    hemen [mysqld] bölümüne;

    tmpdir=/var/tmpfs
    tmp_table_size=2K
    Alanını ekliyoruz ve mysql sunucusuna restart atıyoruz. Bundan sonra cacheler ramde tutulacak ve hdd verilerine göre çok daha hızlı olacaktır.

    Bu arada küçük bir püf nokta vereyim.

    Lütfen tablo yapılarınızı MyIsam kullanmayınız. Sene 2020 MyIsam bundan 10 sene önce dandik sunucularda performanslı olabilirdi fakat mysql tablo yapısı her insert değer için tüm tabloyu lock edip beklemeye alır insert işlemi bitene kadar o yüzden bunun yerine async calışan ve lock etmeyen innodb kullanın.

    Tek sorgularda myisam'e göre 0.002 saniye yavaş olabilir fakat tüm işlemler baz alındığında 50 kat daha performans sağladığını göreceksiniz ve bu kanıtlanmış bir gerçektir.

    Saygılar.
    Baştan sona okudum. R10'da bu tarz konular görmek çok güzel. Emeğinize sağlık o kadar yazmışsınız. Peki MysIsam ile InnoDB motorlarının arasındaki fark genellikle insert işlemlerinde mi ortaya çıkıyor. Mesela big datalarda gözlemlediğiniz durumlar nasıldır?
  • 19-03-2020, 02:22:36
    #4
    ram'de session saklamakla aynı olsa gerek. sunucunun memory hatası vermesine sebep olmuyor mu ?

    Saygılar.
  • 19-03-2020, 02:22:59
    #5
    Hocam selamlar,

    Bilgi paylaşımınız için çok teşekkür ederim.

    Bir eticaret sitem var 600k civarında ürün var. Bu dediklerinizin hepsini hali hazırda kullanıyorum. Sizden de aynı şeyleri duyunca yaptığım çalışmanın yanlış olmadığını anladım.

    Hatta buna ekstra olarak file cache sistemleri de kurdum. Her defasında yeni sorgu yapılmasına gerek kalmadan direk filecache basıyorum ekrana ve sql'e gidip gelmesi ile filecache okuması arasında yaklaşık 4-5 sn fark oluyor. (filecache çok hızlı çalışıyor)

    Ancak hala ilk giriş gecikmesi denilen ilk istekte 4-9sn arası gereksiz bi takılma ile başım dertte. Nelere bakmam gerekir?
  • 19-03-2020, 02:31:02
    #6
    Baştan sona okudum. Emek verilmiş ve zaman harcanmış bilgilendirici bir konu olmuş.
  • 19-03-2020, 02:59:51
    #7
    Eline koluna klavyene sağlık üstad. Mesajım burada kalsın dönüp dönüp bakacağım zira
  • 19-03-2020, 08:06:27
    #8
    fskgrup adlı üyeden alıntı: mesajı görüntüle
    Hocam selamlar,

    Bilgi paylaşımınız için çok teşekkür ederim.

    Bir eticaret sitem var 600k civarında ürün var. Bu dediklerinizin hepsini hali hazırda kullanıyorum. Sizden de aynı şeyleri duyunca yaptığım çalışmanın yanlış olmadığını anladım.

    Hatta buna ekstra olarak file cache sistemleri de kurdum. Her defasında yeni sorgu yapılmasına gerek kalmadan direk filecache basıyorum ekrana ve sql'e gidip gelmesi ile filecache okuması arasında yaklaşık 4-5 sn fark oluyor. (filecache çok hızlı çalışıyor)

    Ancak hala ilk giriş gecikmesi denilen ilk istekte 4-9sn arası gereksiz bi takılma ile başım dertte. Nelere bakmam gerekir?
    Tam olarak ilk giriş derken pagespeed ile alakalı bir kavram mı bu ilk giriş. Tam anlayamadım. Yoksa database'e ilk veri girerken mi? Eğer pagespeed ile alakalı sayfayı ilk yüklemeye calıştığı değerden bahsediyorsan. Oluşturmayı önleyici javascript ve style dosyalarını footer'a alıp. Tasarımın ilk görünüşte bozulmaması içinde en gereklilerini http header ile preload edebilirsin. PHP için örneğin wp kullanıyorsanız:

    add_action('init','preloadHeaderAyarlarim');
    function preloadHeaderAyarlarim() {
        if (!is_admin()) header("Link: </wp-content/themes/temaadi/style.css>; rel=preload; as=style;");
    }
    gibi.



    M_D_5 adlı üyeden alıntı: mesajı görüntüle
    Baştan sona okudum. R10'da bu tarz konular görmek çok güzel. Emeğinize sağlık o kadar yazmışsınız. Peki MysIsam ile InnoDB motorlarının arasındaki fark genellikle insert işlemlerinde mi ortaya çıkıyor. Mesela big datalarda gözlemlediğiniz durumlar nasıldır?
    Sadece insert demek hatalı olur. Bunu tablonun lock olması olarak düşünelim. Anlık 5K online olan bir internet siteniz olduğunu düşünün. Bu bağlantılardan 300 ü sql'e insert veri girdiren bir işlem yapiyor olsun. Eğer tablo yapınız myisam ise 300 insert işlemi de tabloyu sırasıyla lock edecek anlamına gelir. Ve diğer geri kalan 4K istek query olsun. Lock olan tablodan query cekemeyecekleri için sıralarını bekleyecekler. Eğer bu bekleme olayı artarsa üst üste binecek anlamına gelir ve her beklenen mili saniye sunucuya daha fazla yük olarak geri döner ve sunucunun rahatlaması imkansız bir hale gelir.

    Big datadan kastınız tam olarak nedir? Bunu neden soruyorum bazı arkadaşlar full text 3 5 sayfa tutacak yazıyı big data sanıyor o yuzden. Ciddi ciddi 1 verinin 300 500mb tuttuğu gerçek big datadan bahsediyorsanız örneğin video ses dosyaları gibi. Bunlar için mysql kullanmak büyük saçmalık olur. Hatta kendi x bir datacenter da bulunan server da tutmak dahi saçmalık olur.

    Çünkü bu tür veriler sunucunun aylık kirasından cok daha değerlidir. Büyük veriye sahip oldukları için kaybolma ve yeniden oluşturma riskleri zaman ve esktra efor anlamına gelir. Buda çok büyük hamallık demek.Bu hamallığa düşmemek ve ekstra efor sarfetmeyip %100 güvenli hale getirmek adına ben olsam Google, AWS gibi bigdata hizmeti veren sistemlerde depolar kafam rahat ederdim.

    Hem optimizaasyonla uğraşmazdım, hem de veriler bozulur mu, acaba kaybolur mu düşüncesi beni boğmamış olurdu.
  • 05-04-2020, 22:58:11
    #9
    Çok güzel hazırlanılmış bir yazı. Tebrik ve teşekkür ediyorum, elinize sağlık. Bu tür kaliteli paylaşımların sayısı artması dileğiyle.