opcache

Php 5.5 Opcache Nedir? (ve overflow problemi)

Opcache Nedir?

PHP 5.5 üzerinde hazır halde gelen opcache temel olarak, filesystem üzerinde bulunan php dosyalarını her requestte okumamak için tasarlanmış bir otomatik low level cache mekanizmasıdır. Php nin 5.5 sürümünü kullanıyorsanız, ve özellikle kapatmadıysanız, muhtemelen siz de bu özelliği kullanabilirsiniz / veya zaten bilmeden kullanıyorsunuzdur.

PHP interpreted bir dil olduğu için, (yazılan kodlar, çalışma anında makine diline çevrildiğinden) ilgili dosyalar normalde her çalıştırdığınızda veya sitenize her request geldiğinizde tekrar tekrar bu dosyaları load eder. Düşünün bir siteniz var ve anasayfasını ekrana basmak için 10 adet php dosyasına ihtiyacınız var. Sitenize de aynı anda(örneğin 1 saniye içinde) 100 kişi giriyor. Opcache olmadığında, bu 10 dosyayı her 100 giriş için toplamda diskten 1000 kere okuma işlemi yapması gerekiyor. Halbuki opcache üzerinde bir ayar ile bir dosyayı okuduğunda 10 saniye boyunca cachelemesini belirtebilirsinz. Bu demektir ki, 100 kişi x 10 saniye x 10 dosya = sisteminizin 10.000 kere okuma yapması gereken halde, sadece 10 kere diskten okuma işlemi yapacaksınız. Tabi, yapacağınız bir dosya değişikliğinin sitenize yansıması için bu sefer 10 saniye beklemek zorunda kalacağınızı da hatırlatmak isteriz.

Default değerleri görebileceğiniz tüm opcacahe konfigürasyon listesi için buyrunuz : http://php.net/manual/en/opcache.configuration.php

Opcache ile tam olarak ne kazandık? 

Tam olarak io kazandık, (diskten okuma yapma işlemlerimizi, sitemizin yoğunluğuna göre %100 e yaklaşan bir değere kadar azaltabiliriz.)

Dezavantajları neler?

Developer ortamında, insan bir şeyi denerken hemen dosyayı kaydedip yaptığı değişikliği anında  görmek isteyebilir. Hatta refleks olarak böyle davranır yazılımcılar. Bu durumda, local ortam için bir miktar handikap oluşturabilir, veya en güzeli, local ortam için opcache i disable etmek olabilir. (php.ini içinde opcache.enable=0 yazacaksınız) Aksi halde zırt pırt fpm restart etmek zorunda kalabilirsiniz.

Başka başka?

Opcache; büyük bir projede, aynı dosyalar ile çok fazla takıldıktan sonra, yazılımınızın yeni bir versiyonuna ait benzer sayıda çok dosya daha geldiğinde, ve artık bu dosyaları kullanmaya başladığında, sanırım eski dosyaları halen aklında tutmaya çalışmasından dolayı, yeni dosyalarınızı okurken io’su sanki opcache açık değilmişçesine artmaya ve overflow olmaya başlıyor. (bu da load vb konularında probleme sebebiyet verebiliyor. ). Çalışmamazlık durumu oluşmuyor ancak code ve dosya sayısı büyüklüğünüze göre sizi olumsuz etkiliyor. Bu noktada codebase üzerinde çok fazla değişme/yeni release yayına alma gibi aksiyonlarda php-fpm inizi restart etmenizde yarar var. (reload kurtarmıyor malesef)

Bir Klasördeki Optimum Dosya Sayısı (optimum file count in a directory)

Bir sunucunuz varsa, içerisinde bir sürü hesabınız varsa veya bir sunucudaki birden çok hesabı yönetiyorsanız, bu anlatacağım en çok sizi ilgilendiriyor. Herkes için de faydalı bir bilgi tabi ki.

Bir yazılımda cache, temp vb. klasörler olmaktadır. Yalnız, bu klasörlerin içeriği dinamik olarak kısıtlanmadığından veya kısıtlanmasının maliyetinden dolayı, klasördeki dosya sayısı çok dinamik olarak artacaktır.

Normalde bir klasöre elle de çok fazla dosya atmış olabilirsiniz. Bu da benzer bir durumdur. Örneğin, bir ürün kataloğunuz var ve resimleri katalog klasörünün altına koydunuz.

Bu noktada önerimiz bir klasör içine 3000-5000 den fazla dosya koymayın. Bu tabi direkt bu sayı olarak söylemem zor ama yine de 10000’den kesinlikle fazla olmasın. Alt klasörden bahsetmiyorum, dosyadan bahsediyorum. Burada alternatif olarak katalog klasörünün içine 01/, 02/ diye klasörler açıp 500 500 koymakta yarar var.

Kendinizi işletim sisteminin yerine koyun. Elinizde bir adres var, içinde yığınla insan var. Siz içlerinden daha önce tanışmadığınız birini arıyorsunuz, kendisinden bir bilgi alacaksınız. Bulmanız çok zor. Özellikle bu içerideki kişilerin isimlerinin ilk birkaç karakteri aynı ise, o zaman iş daha da zorlaşır. Bu noktada belirtilen adreste odalar koysanız, insanları da alakalı oldukları yere göre odalara koysanız, (odalar burada klasör manasına geliyor, yapılan işlem de klasör oluşturarak manuel indeks oluşturmak) aradığınız şeyi hangi odada arayacağınızı bildiğiniz sürece işlemini hızlanacaktır. Ki zaten klasör ismini biz veriyorsak, olumlu etki edecektir.

Benim gibi bir cache klasöründe 40000 tane dosya oluşmasını ve hatayı tespit etmek için serverda cirit atmanız gerekmeden bu bilgiyi öğrenebilirseniz ne güzel. 40000 dosya (zend_cache dosyası) içinden php, ilgili dosyayı load edesiye kadar mysqlden çekse çok daha hızlı olacaktı halbuki. (cache tamamen ters bir mantığa dönmüştü). Dinamik bir cache mantığı vardı.

Olayı da şöyle tespit ettim ; mysqlde doğru düzgün query düşmüyordu. Sunucuda top komutu çalıştırdığımızda httpd isteklerinin normalden 2-3 kat cpu harcadığını gördük, bağlantı sayısı da normalden azdı. Biz de ilk önce mail sunucusu veya yedekleme ile ilgili bir sorun oluştuğunu düşündük fakat, gelen isteklerin yoğunluk yaratan hesaplardan birinin cache klasörüne girip baktığımda bu tabloyla karşılaştık. Bu dosyaları temizlediğimizde ise makinadaki stres tamamen gitti. (Bu konuda yazılım geliştirmesi ile görev oluşturduk, ve gelişimi için gerekli aşamalara başladık.)

Bu bilgiyi tecrübe ederek öğrenmemeniz dileğiyle, iyi çalışmalar dilerim.

Memcache in Telnet ile kullanımı

Memcache’in telnet üzerinden kullanımı.
Linux işletim sisteminde de ps -ef komutuyla memcache’in hangi porttan çalıştığını görebilirsiniz.

Memcache başlamadıysa konsoldan

memcached -m 128 -l localhost -p 11211 -d -u nobody

yazarak başlatabilirsiniz. (bu kod 128 MB ram ile 11211. porttan, nobody olarak çalıştırır.)
Yine konsoldan

telnet localhost 11211 

yazarak bağlanınız.

Supported Commands

Example
get deneme //varsa deneme adlı memcache verisini getirir.
set deneme 0 60 5 //koşulsuz olarak deneme verisini set eder
add deneme 0 60 5 // deneme adlı yeni bir key oluşturur.
replace deneme 0 60 5 // deneme verisinin yerine yenisini yazar.

append deneme 0 60 15 // deneme key’inin sonuna veri ekler
prepend deneme 0 60 15 // deneme key’inin başına veri ekler
incr deneme 2 // değeri sayısal olarak verilmiş deneme değerinin değerini 2 artırır.
decr deneme 5 // değeri sayısal olarak verilmiş deneme değerinin değerini 5 azaltır.
delete deneme // deneme adlı key i siler.

flush_all // bütün belleği boşaltır.
flush_all 900 // 900 saniye içindeki tüm verileri boşaltır.

stats // genel istatistikleri basar.
stats slabs // bellek istatistiklerini basar.
stats malloc // bellek istatistiklerini basar.

stats items
stats details
stats sizes // daha yüksek seviyeli atama istatisiklerini basar.
stats reset // istatistikleri sıfırlar.
version // versiyonu basar.
verbosity // loglama seviyesini artırır.
quit // telnet oturumunu kapatır.

Bunlardan benim telnetten en sık kullandıklarım flush_all ve stats’dır. Diğer konulardaki işlemleri ilgili yazılım dillerinde yaptığımızdan, sadece istatistikleri görmek (kaç istek var kaçı memcacheten okudu, kaçında isabet var vb.. gibi..) benim için telnetten yeterli olabiliyor. Veri set etme ve replace etme olaylarını ben deneme hariç kullanmadım diyebilirim. Yine de ihtiyaç duyulabilir ve kullanılabilir.

Windows Memcache Kurulumu (Windows 7 Dahil)

Memcache modülünün Windows üzerinde çalışan php-apache üzerine kurulması :

  1. Php extensions klasörünü kontrol edin. C:\php\ext gibi bir şey olması gerekiyor. (Wamp kullanıyorsanız c:/wamp/bin/php/php5.3.4/ext gibi bir şeydir.)
    Bu klasörün içinde php_memcache.dll adlı dosyanın olup olmadığına bakın. Yoksa bu dosyayı bir şekilde edinin. Buradan indirebilrisiniz isterseniz : http://downloads.php.net/pierre/php_memcache-2.2.6-5.3-nts-vc9-x86.zip
  2. Şimdi sistemde kullanılan php.ini dosyanızı bulun. wamp için wamp klasöründe bir yerlerde oluyor. Sağ alttaki wamp simgesine tıklayıp orada php kısmında php.ini ye basınca gelen dosyadır.
    bu dosyanın sonuna bir yere yeni bir satırda
    extension=php_memcache.dll yazın kaydedin.
  3. Apache nizi restart edin.
  4. memcached.exe yi çalıştırın. Buradan edinebilirsiniz : http://www.splinedancer.com/memcached-win32/
    Normalde, memcached.org adresinde de var fakat, compile edilmemiş hali var ve compile etmek için bir sürü teane gerekiyor. İsterseniz oradan kurun.
    Memcached.exe çalışınca bir siyah pencere açılacak ve orada kalıcak, anormal bişey yok, (servis olarak arka planda çalıştırmak ile farkı yok, birazdan onu da anlatacağım.)
  5. Aşağıdaki kodu çalıştırın
    < ?php
              $memcache = new Memcache;
              $memcache->connect("localhost",11211); # varsayılan ayar olarak memcache 11211 protu kullanır. belki localhost yerine 127.0.0.1 yazmanız gerekebilir.
    
              echo "Memcache versiyonu: " . $memcache->getVersion() . "
    \n"; $tmp_object = new stdClass; $tmp_object->str_attr = "test"; $tmp_object->int_attr = 123; $memcache->set("key",$tmp_object,false,60); echo "Veriyi cache'te sakla.(Veri 60 saniye boyunca cachete tutulacak.)
    \n"; echo "cacheten okuduğum değer :
    \n"; var_dump($memcache->get("key")); ?>
  6. Ekrana hata yerine yukarıdaki şeyleri görüyorsanız, memcache’iniz çalışıyor demektir.
    Memcacheinizi denemenizin bir diğer yolu da telnet üzerinden bağlanmaktır. (windowsunuzda telnet hizmetini aktif etmeniz gerekiyor, eğer açık değilse, bu konuyu zorlaştırmamak için burada anlatmıyorum.)
    cmd’den

    telnet localhost 11211 
    

    diyeceksiniz. Bağlanırsa, tamam çalışıyordur. (Telnetten memcahce kullanabilemk için de ilgili parametreler vb ile ilgili bir yazı ekleyeceğim)

  7. Extra not : memcached.exe yi arka planda çalışan servis olarak çalıştırmak için cmd yi yönetici yetkisiyle çalıştırın. (ctrl+shift+click).
    Daha sonra

    c:/memcachein_bulunudugu_dizin/memcached.exe -d install
    c:/memcachein_bulunudugu_dizin/memcached.exe -d start
    

Ve windowsunuza memcache kurdunuz. Şimdi yapmanız gereken bir kaç uygulama geliştirip, memcache’in avantajlarını keşfetmek. Memcache günümüzde bir çok büyük firma site vb tarafından stabil bir şekilde kullanılıyor. Bunlara da başka bir yazıda değinmek dileğiyle.

Önemli Not : Php 5.3 te biraz araştırdım ama çalışan bir workbench oluşturamadım. Yapan olursa paylaşmasını rica ederim.

zend cache (zend file cache) to memcache

If you are tending to use memcache while you are currently using Zend File cache, here are some advices for you.

First, if you use “tagging” in file cache (in memcache there is no tag system from its simplicity), you have to create your own tag system manually. (Tag system is for cleaning cache data with the same tag.) When saving a cache id, you have to collect and save the tag and the ingriendents of the tag.

But where to put this self-made tag data?

If you save this in memcache, it is not reliable, while it can be deleted automatically in the lack of memory.

If you save this on a regular file, at this point, if too many visitors come, file locking can reduce your speed, or can not be written correctly (tries to write the same file by multiple ports)

You see, there can be no solution to this issue with tag system.

So I advice you, if you use Zend_File_Cache with tag system, purify your cache data from tags, or create a static tag array in your php code. There can be only this method that comes to the state “solution”.