Sayfalar

8 Ocak 2011 Cumartesi

PHP & Memcache

Memcached & Php Nedir ?
Memcached "Danga Interactive" ( http://www.danga.com/ ) tarafından LiveJournal için geliştirilen dağıtık , nesne tabanlı tampon bellek sistemidir ( distributed memory object caching system , biliyorum kötü bir çeviri ).
Proje Live Journal için geliştirilsede , Facebook en büyük destekçisi haline gelmiştir : yazılım üzerinde yaptıkları değişiklikle işlemci kullanım oranını %20 azaltırken, bellek kullanımında %30'luk bir iyileştirme yapmışlardır ( http://developers.facebook.com/opensource.php ) ; aynı zamanda mamcached kurulu en büyük yapı facebook'da bulunmaktadır. ( http://lists.danga.com/pipermail/memcached/2007-May/004098.html , 200 X 16GB 4 Çekirdekli Amd64 Sunucu )

Nerede kullanılır ?
Sık talep edilen bilgileri sunmada ve veritabanını belirli ölçüde rahat bırakmada kullanılır. Hiç şüphe yokki belleğe erişim, diske erişimden daha hızlıdır. Veritabanlarının tamponlama ( caching ) özelliği olsada duruma göre memcached dağıtık yapısı nedeni ile tercih edilebilir.

Web sitelerinde kullanım yerleri olarak ;
+ Giriş işlemlerinde kullanıcı oturumlarının saklaması,
+ Siteiçi aramalarda , çok sık yapılan aramalar için kelimeler ve sonuçlarının hafızada saklanması,
+ Günlük yada haber sitelerinde ilk sayfada çıkan haberlerin hafızda saklanması, örnek verilebilir.

Nasıl ?
Kurulum kullandığınız dağıtıma göre değişmekle beraber, Ubuntu üzerinde
#apt-get install memcached php5-memcache
komutu ile kurulum işlemini gerçekleştirebilirsiniz.
!!! Ubuntu & Php-5 için not : Apt-get kurarken php.ini'de ufak bir hata yapıyor , /etc/php5/apache2/php.ini 'de
-e extension=memcache.so
olan satırı bulup, fazlalık olan "-e "yi silmeniz
gerekiyorr son hali
extension=memcache.so olmalı Apt-get yazılımları yükledikten sonra /etc/memcached.conf dosyasını açıp "-m 64" değerini bulun, varsayılan olarak memcached 64Mb ram kullanmaktadır, mevcut ram miktarınıza göre uygun bir değer girin. Dikkat: bu alana sahip olduğunuz tüm belleği girmek gibi bir hata yapmayın.
Kurulum işlemini apache'yi ve memcached'ı yeniden başlatarak tamamlayın.


<?
// Yeni bir memcache nesnesi oluştur
$memcache = New Memcache();
// Sunucu üzerinde kurulu olan memcached sunucusuna bağlan
$memcache->connect('localhost', 11211) or die("Memcache:> Bağlantı kurulamadı...");
// Sunucu üzerinden "kayit" nesnesini al
$kayit = $memcache->get('kayit');
// Eğer kayit nesnesi daha önceden atanmamışsa değer ata
if( !$kayit )
{
$kayit['sayac'] = 0;
$kayit['zaman'] = time();
// $kayit değişkenini, sunucu üzerinde "kayit" nesnesi olarak
// 10sn için hafızaya ata.
$memcache->set('kayit', $kayit, false, 10);
}
else
{
// $kayit değişkenindeki sayacı arttır.
$kayit['sayac']++;
if( $kayit['sayac']++ == 25 )
{
$memcache->delete('kayit');
echo "Memcache'den , 'kayit' nesnesi kaldırıldı..";
return;
}
// sunucu üzerindeki kayit nesnesini güncelle
// false: değişkenin ziplenerek saklanması istebiyorsa TRUE olmalıdır;
// 10 : değişken güncellenirken, ne kadar süre daha hafızada kalacağıda
// ayarlanabilir
$memcache->replace('kayit',$kayit, false, 10);
}
printf("Zaman : %s , Sayac: %s ", date("h:i:s d.m.Y", $kayit['zaman']), $kayit['sayac'] );
?>

Örnek-1 'de

3..6. Satırlar......:
ilk olarak bir memcache nesnesi oluşturulmakta ardından, memcache kurulu sunucuya ( localhost ) , memcached'ın varsayılan portu olan 11211. port'dan bağlanması sağlanmaktadır.

9. Satır.............:
Sunucu'dan 'kayit' nesnesi alınmakta ve $kayit değişkenine atanmakta.

12..20. Satırlar :
Sunucu'da kayit nesnesi bulunamazsa , yeni bir dizi oluşuturulup bu dizi'de 'sayac' elemanına 0, 'zaman' elemanına o anki zaman atanmakta ve $memcache nesnesinin "set" fonksiyonu ile $kayit dizisi , sunucuda 'kayit' nesnesi olarak oluşturulmakta. Set fonksiyonundaki 10 ifadesi , saniye cinsinden kayıdın sunucuda ne kadar süre ile hafızada tutulacağını belirtiyor, eğer bir değer vermezseniz bu varsayılan olarak 30 gün'dür ve 30 günün sonunda bu nesne silinecektir.

23..32. Satırlar:
Sunucu üzerinde bulunan kayit nesnesini 9. satır'da $kayit değişkenine atamıştık, bu değişken bir dizi ve bu dizi
üzerindeki 'sayac' elemanın değerini bir arttırıyoruz. Eğer bu değer 25'e eşit ise memcached sunucusu üzerindeki kayitnesnesi, $memcached objesinin "delete" fonksiyonu ile siliyoruz. Neden böyle birşey yapma ihtiyacı içerisindeyiz ?
Açıkcası bu gayet sıkıcı bir örnek ve ortama eğlence katmak lazım , bilgisayarımızı camdan aşağıya atamıyorsak bizde
değişkenlere saldırırız :)
37. Satır......:
Sunucuda nesnemiz bulundu , $kayit dizisnde sayac değerini arttırdık fakat bu değer 25'in altında o zaman yapılacak tek birşey kalıyor : yeni değeri güncellemek. $memcache nesnesinin replace fonksiyonu tam bu işe yarıyor ve set ile benzer parametreleri alıyor. 10 değeri bu arada nesnenin hafızada kalma süresini tekrar 10 sn yapıyor. Sanırım işleyiş mantığını anlamaya başladınız. Kullanıcı giriş bilgilerini veritabanı ile olan iletişimi en aza indirmek için memcache ile hafızada tutmak isterseniz aşağı yukarı şunun gibi bir fonksiyon kullanmanız lazım :

function Giris ($kullanici, $parola )
{
$memcache = New Memcache();
$memcache->connect('localhost', 11211) or die("Memcache:> Bağlantı kurulamadı...");
$kayit = $memcache->get( 'giris:' . $kullaniciadi );
if( !$kayit )
{
$sorgu = mysql_query("Select * From Kullanicilar Where kullanici='$kullanici' and parola='$parola' Limit 0,1");
if( mysql_num_rows($sorgu) < 1 )
return FALSE;
$kayit = mysql_fetch_array($sorgu);
$memcache->set('giris:'.$kullaniciadi , $kayit, false, 10);
}
else
{
if( ($kayit['kullanici'] != $kullanici) && ($kayit['parola'] != $parola ) )
return FALSE;
}
return TRUE;
}

Kodun yaptığı kabaca , memcached sunucusunda kullanıcı bilgilerinin olup olmadığına bakmak, yoksa veritabanına bağlanıp kullanıcı bilgilerini almak ve kayıt dönerse ( = kullanıcı bilgileri doğru ise ) bunu memcached'da bir nesne olarak atamak. Eğer memcached üzerinde kullanıcı bilgilerini bulursa onun üzerinden kontrolleri yapmak. Php'nin oturum bilgilerini memcache üzerinde tutmasını sağlayabilirsiniz. Yanlız burada debian/ubuntu kullanıyorsanız ufak bir sorun var : oturum bilgilerini memcached'da tutmanız için php-memcached eklentisinin versiyon numarasının 1.80 yada daha büyük olması lazım ve debian/ubuntu ile eski versiyonlar geliyor. Uzun uzun anlatmak ve hazırda olan bilgileri tekrarlamaktansa , program nasıl derlenir bildiğinizi varsayıyorum ve gerekli bilgileri almanız için sizi http://www.lullabot.com/articles/how_install_memcache_debian_etch adresine yönlendiriyorum. Oturum bilgilerinin memcached üzerinde tutulmasını iki şekilde ayarlayabilirsiniz :
session.save_handler = "memcache"
session.save_path = "tcp://localhost:11211?persistent=1&weight=1&timeout=1&retry_interval=15"
2- .php dosyanızda , session_register'den önce şöyle bir şey ekleyerek :
ini_set('session.save_handler', 'memcache');
ini_set('session.save_path' , 'tcp://localhost:11211?persistent=1&weight=1&timeout=1&retry_interval=15');

 Dökümanı bitirirken bahsetmediğim bir fonksiyon hakkında ufak bir bilgi vermem gerekli: Memcached'ın dağıtık bir sistem olduğunu söylemiştik, php dosyamızın diğer memcached sunucuları ile bağlantı kurması için "addServer" fonksiyonu kullanmamız lazım. 2x1Gb ram ve 1x2Gb ram'i olan 3 makineli bir ağ için örnek :
$memcache = New Memcache();
$memcache->connect('localhost', 11211) or die("Memcache:> Bağlantı kurulamadı...");
$memcache->addServer( 'memc1.local.net' , 11211, TRUE, 10);
$memcache->addServer( 'memc2.local.net' , 11211, TRUE, 10);
$memcache->addServer( 'memc3.local.net' , 11211, TRUE, 20);

memcX.local.net : memcached kurulu olan diğer sunucu
11211 : memcached portu
TRUE : kalıcı (= persistent ) bağlantı yapılacak
10/20 : işte eğlenceli kısım ; yük dağılımı. Büyük rakam = fazla ram = Daha fazla başvurulacak makine.

Sonuç & Notlar Memcached , yoğun trafik alan sunucularınızı biraz rahatlatmak için kullabileceğiniz güzel bir oyuncak bununla beraber ağır çalışma ortamlarında test edildiği için deneyip kendi durumunuzda işe yaradığını görürseniz kullanmamanız için hiçbir sebeb yok. Memcached & Apache yeterli ram olduğu sürece aynı makinede çalışabilir, genel olarak memcached belleğe apache işlemciye yüklenir..

Hiç yorum yok:

Yorum Gönder