13 listopad, 2008

PHP i memcached

Memcached je, jednostavno rečeno, servis za spremanje podataka u memoriju. To je posebno korisno u slučajevima kad je pristup bazi prespor (previše upita, spori SQL-ovi, ...).

U većini aplikacija to nije toliko važno jer, dok je aplikacija pokrenuta - sve funkcije, klase i varijable već imaju svoje mjesto u memoriji. Međutim, kod web aplikacija baziranih na (nekim) skriptnim jezicima kod kojih svaki klijentski zahtjev (request) pokreće iznova skriptu - stvar je drukčija... Zato što pojedina pokretanja iste skripte nemaju pristup zajedničkim podacima iz memorije.

Taj problem se može izbjeći snimanjem u datoteku i/ili bazu podataka. Međutim, čitanje u memoriju i iz memorije je puno efikasnije i od baze i iz datoteke.

Evo, zato, šalabahter o osnonim funkcionalnostima PHP memcachea, možda još nekome bude od koristi:

Instalacija
Memcached je poseban servis koji treba biti startan na serveru (ili više servera). Na ubuntu je to paket memcached. Treba ga startati s /etc/init.d/memcached start. Servis čeka na portu 11211.

PHP-u, za pristup servisu treba Ubuntu paket php5-memcached, a u php.ini dodati liniju extension=memcache.so.

Sigurnost
Memcached nema nikakvu sigurnostnu podršku. To znači da svatko tko ima pristup portu 11211 može koristiti servis i petljati po vašoj memoriji Vaše aplikacije! Zbog toga treba:
  • U memcached.conf paziti da linija bude odkomentirana linija -l 127.0.0.1, koja određuje da se servisu može pristupati samo s lokalnog stroja. Ili promijeniti tu istu liniju i zapisati s kojeg servera se može pristupati,
  • Servis držati na serveru koji je sakriven iz vatrozida (firewalla).
Funkcionalnost
Memcached, u stvari, nije ništa drugo nego veliki skup ključ/vrijednost parova. Ključevi su stringovi, a vrijednost može biti bilo što. Svaki par ima svoje vrijeme trajanja nakon kojeg se automatski briše iz memorije. Kad spremimo novu vrijednost s istim ključem - stara se briše (odnosno pregazi).

Vrijednosti se mogu čuvati kompresirane.

Postavke
Sve postavke servisa se mijenjaju u /etc/memcached.conf. 

PHP API

Inicijalizacija:
$memcache = new Memcache();
$memcache->connect( '127.0.0.1', 11211 )
    or die( 'Could not connect' );

Verzija:
echo 'Verzija memcacheda je ' . $memcache->getVersion() . '<br/>';

Spremanje u memoriju:
$memcache->set( 'početak', 'u početku bijaše riječ' );

Rečenica iz memorije pod ključek 'početak' je sad dostupna iz bilo koje druge PHP skripte s:
$memcache->get( 'početak' );

Ista rečenica se može spremiti u kompresiranom obliku, tako da zauzima manje memorije:
$memcache->set( 'početak', 'u početku bijaše riječ', MEMCACHE_COMPRESSED );

Napisah već da sve spremljeno ima svoje vrijeme trajanja u memoriji. Ukoliko nije drukčije specificirano, ono je 2592000 sekundi (30 dana). Ako treba spremiti na kraći rok:
$memcache_obj->set( 'početak', 'u početku bijaše riječ', 0, 3600 );

...treći argument 0 znači da je spremljeno bez kompresije, a četvrti 3600 znači da je spremjeno na 3600 sekundi (1h).

Slično metodi set() postoji i add() koja sprema vrijednost samo ako ona ne postoji otprije u memoriji.

Razne brojače je korisno čuvati kao brojčane vrijednosti u memcached-ovoj memoriji. U tom slučaju ih se može uvećati ili metodama increment() ili decrement():

$memcache->set( 'brojač', 10 );
echo $memcache->get( 'brojač' ) . '<br/>';
$memcache->increment( 'brojač' );
echo $memcache->get( 'brojač' ) . '<br/>';
$memcache->decrement( 'brojač' );
echo $memcache->get( 'brojač' ) . '<br/>';

Brojač 'brojač' bi iz memorije obrisali s:
$memcache->delete( 'brojač' );

flush() sve trenutne unose označava kao da im je vrijeme isteklo, tako da se memorija koju su do sada koristili može koristiti iznova:
$memcache->flush();

Statistika servera u obliku arraya se može dobiti kao:
$memcache->getStats();

Konekcija na memcached se zatvara s:
$memcache->close();

Osim navedene objektno orijentirane sintakse postoji i funkcijska, na primjer memcache_set() umjesto $memcache->set().

3 komentara:

  1. Odlican tekst! Super ce koristi kada se budem morao igrati s time!
    OdgovoriIzbriši
  2. Pa, ti si krivac :) Enivej, vidim da i sam imaš blog o sličnoj "problematici"...
    OdgovoriIzbriši
  3. Pa daa, ali tema mi je general software development lifestyle
    OdgovoriIzbriši