Memcached - wydajne buforowanie danych

Na pewno często zastanawialiśmy się nad sposobem przyspieszenia swoich witryn internetowych. Wielu z nas korzysta z cahcowania na plikach, jednakże nie zawsze to zdaje egzamin. Dziś chciałbym poruszyć alternatywę czyli memcached. Pozwala on na buforowanie wszelakich danych w pamięci ram, dzieki czemu jest niebotycznie szybki. W odróżnieniu od takich pakietów jak APC, eAccelerator czy JPCache, jego głównym zadaniem nie jest buforowanie stron wyjściowych, tylko samych danych. Z racji iż jestem zwolennikiem buforowania danych(a nie całych stron), odpowiada mi on w stu procentach. Główną przyczyną tego stanu jest to, że często te same dane pobieramy wielokrotnie zmieniająć ich wygląd na wyjściu.

Instalacja

Aby móc w pełni korzystać z dobrodziejst jakimi obdarza nas memcached, potrzebujemy serwera, ponieważ musi on działać w tle non-stop. Jeżeli korzystamy z systemu Linux pobierzemy go z tej strony http://www.danga.com/memcached/ lub znajdziemy najpradopodobniej w repozytoriach, jeżeli jesteś użytkownikiem Windowsa wypada zajrzeć tutaj http://jehiah.cz/projects/memcached-win32/. Po instalacji demona, potrzebujemy do szczęścia jeszcze biblioteki pecl do php. Fedora posiada gotową wersje w swoim repozytorium, nazywa się ona php-pecl-memcache, jak jednak nam się nie poszczęściło to musimy pobrać z http://pecl.php.net/package/memcache lub zainstalować korzystając z polecenia:

pecl install memcache

Niestety dla systemu z Redmond msusimy udać sie pod adres http://pecl4win.php.net/ext.php/php_memcache.dll i wybrac wersje biblioteki dll odpowiednią do wersji PHP.
Musimy pamiętać, że aby wszystko "śmigało" sprawnie w systemie Windows musimy mieć katalog z bibliotekami dodany do zmiennej środowiskowej Path.
na sam koniec musimy właczyć nasze rozszerzenie w pliku konfiguracyjnym php, więc przechodzimy do pliku php.ini i dodajemy bądź odkomentowywujemy linię:

extension="memcache.so"

Dla windows:

extension=php_memcache.dll

Praca z memcache

Kiedy mamy wszystko zainstalowane z powodzeniem uruchomiliśmy demona/usługę memcached, możemy rozpocząć prace z nim.
Jak już pisałem za pomoca mamcached możemy buforowac wszystko od liczb, stringów po nawet obiekty z wyjątkiem tak jak przy serializacji danych, niestety nie uda nam się zbuforowac zasobów, czyli np. połączeń z bazą danych. W przypadku obiektów problem ten można wygodnie rozwiązać za pomocą metod magicznych __sleep() oraz __wakeup(). Kiedy już wiemy co możemy umieścić w cache'u przejdziemy do samej biblioteki memcache, a mianowicie dostarcza ona nam klasę Memcache, która obsługuje serwer. Więc aby nawiązać połączenie musimy najpierw utworzyć obiekt klasy i wywołać metodę connect().

<?php
$cache
=new Memcache;
$cache->connect('localhost');
?>

W naszym przypadku połączymy się z serwerem dostępnym na localhoście i z domyslnym portem. Metoda ta może posiadać jeszcze dwa argumenty. Drugi będzie oznaczał numer portu(domyślnie 11211) na którym działa usługa, a trzeci czas po jakim ma zostać zerwane połączenie w przypadku nie korzystania z niego.
Rozwijając nasz przykład wykonamy prosty licznik kliknięć korzystający z memcached.
Kod licznika:
<?php
class Licznik
{
   private 
$count=0;
   
   
//metoda zwiekszająca licznik o jeden
   
public function incCount(){
      
$this->count++;
   }

   
//metoda zwracająca nam aktualny stan licznika
   
public function getCount(){
      return 
$this->count;
   }
}

$cache=new Memcache;
$cache->connect('localhost');
$l=$cache->get('licznik');

if(
$l===false){
   
$l=new Licznik;
   
$cache->add('licznik',$l,MEMCACHE_COMPRESSED,300);
} else {
   
$l->incCount();
   
$cache->set('licznik',$l,MEMCACHE_COMPRESSED,300);
}
echo 
'Obecny stan licznika wynosi: '.$l->getCount();
$cache->close();
?>

Przeanalizujmy teraz ten kod na sammy początku zdefiniowaliśmy klasę która będzie nam obsługiwała licznik, następnie utworzylismy obiekt Memcache i nawiązalismy połączenie. Po tych operacjach wykorzystaliśmy metodę get(), która podjeła próbe pobrania nam zmiennej o nazwie 'licznik' z memcache. Metoda ta jako pierwszy argument przyjmuje nazwę pod jaka dana zmiennna jest zbuforowana, można zamiast jednej podać tablicę to w odpowiedzi dostaniemy tablicę z wartościami. Drugi parametr to sa flagi, ale nim nie będziemy się zajmować. Przejdźmy do warunku if, trzy znaki równości to nie pomyłka, bowiem metoda get() zwraca nam logiczną nieprawde(false) w przypadku kiedy nie odnalazła wartości dla zmiennej o podanej nazwie. Trzy znaki równości sprawdzają toższamość czyli nie tylko czy równe sa strony, ale także czy maja ten sam typ danych. Możemy to zobaczyć na prostym przykładzie:
<?php
if('1234'==1234) { echo 'Prawda'; } else { echo 'Fałsz'; } //zwróci prawdę
if('1234'===1234) { echo 'Prawda'; } else { echo 'Fałsz'; } //zwróci fałsz
?>

Jeżeli nasza zmienna nie została odnaleziona tworzymy jej obiekt, po czym buforujemy ją. Jeśli natomiast jest w memcachu to zwiększamy licznik o jeden i zapisujemy do memcache. Jak zauważylismy na pewno w przypadku odnalezienia zmiennej nie musimy tworzyć jej obiektu, ponieważ zostanie on nam zwrócony od serwera. Teraz zajmiemy sie argumentami metod add() i set() Obydwie przyjmują takie same argumenty. Pierwsze dwa to nazwa klucza, czyli nazwa pod którą będzie wystepować nasza zminna w cache'u, drugi to zawartość naszej zmiennej. Dwa ostatnie argumenty są opcjonalne, pierwszy z pary określa flage, do dyspozycji mamy jedną, która mówi nam czy zawartość ma być kompresowana, drugi argument określa czas(w sekundach) przez jaki dana wartość ma być dostępna w buforze.
Na sam koniec wyświetliliśmy obecny stan licznika oraz zamkneliśmy połaczenie z serwerem.

Sam licznik moglibyśmy wykonac dużo prościej z pomoca memcached. Otóż nasza biblioteka z dostarcza dwie metody do wygodnej obsługi counterów - increment() i decrement(). Obie moga przyjmowac dwa argumenty, ostni jest opcjonalny i określa o ile ma się podnieść lub zmaleć wartość o nazwie określonej pierwszym argumentem metody. Przykład nasz wygladałby wtedy tak:

<?php
$cache
=new Memcache;
$cache->connect('localhost');

if(
$cache->increment('licznik')){
   
$cache->add('licznik',0);
}
echo 
'Obecny stan licznika wynosi: '.$cache->get('licznik');
$cache->close();
?>

Inne metody klasy Memcache

Innymi przydatnymi metodami będą:

  • flush() - metoda ta nakazuje memcache usunięcie wszystkich elementów z bufora, nie przyjmuje ona żadnych wartości. Przykład wywołania: <?php $cache->flush(); ?>
  • delete() - metoda ta nakazuje memcache usunięcie elementu o podanej nazwie, którą podajemy jako pierwszy argument. Opcjonalnie możemy dodać drugi, co spowoduje usunięcie elementu po zadanej ilości sekund, jeśli chcielibyśmy usunąc nasz licznik z bufora wykonalibyśmy <?php $cache->delete('licznik'); ?>. Funkcja zwraca true w przypadku powodzenia lub false jeżeli z jakis przyczyn nie można usunąć elementu, tudziez nie istnieje.

Opis innych metod możemy znaleźć w dokumentacji php pod adresem http://pl.php.net/manual/pl/book.memcache.php.

Your rating: Brak Ocena: 5 (1 vote)

Dodaj nową odpowiedź

Zawartość pola nie będzie udostępniana publicznie.
  • Adresy internetowe są automatycznie zamieniane w odnośniki, które można kliknąć.
  • Dozwolone znaczniki HTML: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Znaki końca linii i akapitu dodawane są automatycznie.
  • You can use the <go> tags just like the <a> for nicer urls.

Więcej informacji na temat formatowania