20091210

Tutorial de memcache

Memcache es una extensió de PHP que interactua amb memcached, que a la seva vegada es un daemon de cache en memoria, molt simple, que enmagatzema parells key=>value on value pot ser qualsevol cosa serialitzable amb PHP.

Per instal.lar amb Ubuntu farem el següent:
apt-get install memcached
apt-get install php5-memcache

Reiniciar apache:
/etc/init.d/apache2 restart

Es pot fer un php amb un phpinfo(); per veure si hi ha un apartat memcache

Per veure si esta funcionant el memcached (el daemon):
netstat -tap | grep memcached

Per modificar els parametres de memoria etc. editar /etc/memcached.conf

per exemple, per configurar 300Mbs de memoria disponible per variables a memcached modificarem el flag -m del fitxer de configuració:
-m 300

Reiniciar memcached
/etc/init.d/memcached restart

Per consultar les estadistiques en temps real del memcached:

telnet localhost 11211
>stats

Exemple de output:


Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
stats
STAT pid 4666
STAT uptime 153661
STAT time 1260523656
STAT version 1.2.2
STAT pointer_size 64
STAT rusage_user 4.850000
STAT rusage_system 15.100000
STAT curr_items 16001
STAT total_items 57971
STAT bytes 282532500
STAT curr_connections 1
STAT total_connections 120074
STAT connection_structures 32
STAT cmd_get 120016
STAT cmd_set 57971
STAT get_hits 66178
STAT get_misses 53838
STAT evictions 0
STAT bytes_read 1108602586
STAT bytes_written 1317300490
STAT limit_maxbytes 314572800
STAT threads 1
END


Ara només cal modificar el nostre codi per enmagatzemar rows de la base de dades, durant un cert temps, en aquests exemples, creem una clau $action.'/'.$param1.'/'.$param2 o sigui per exemple 'category/23/1' i el valor serà el resultat de la base de dades (una array de rows).

La instrucció set enmagatzema a memcached:

$mc->set($action.'/'.$param1.'/'.$param2, $rows, 1, 3600);

El primer parametre es la clau, el segon el valor, el tercer si volem comprimir el contingut o no i el quart el temps en segons que tindrem el valor al memcache (1 hora)

La següent vegada que haguem de fer la consulta farem el següent:

$rows=$mc->get($action.'/'.$param1.'/'.$param2);

Si ens retorna null, es que no hi es, pero durant una hora, no ens caldrà repetir la consulta.

Exemples de codi:


function get_last($num=16, $offset=1, $flag = 1)
{
$sql = "SELECT v.*
, p.title portal_title
, p.url portal_url
, p.id portal_id
FROM ep_videos v, ep_portals p
WHERE v.portal_id = p.id
AND v.status = 'O'
ORDER BY v.added DESC
LIMIT ".(($offset-1)*$num).", ".$num;

$action='home';
$param1='1';
$param2=$offset;
$mc=new Memcache;
$cr=$mc->connect('localhost', 11211);
if ($cr)
{// tenim memcached
$rows=$mc->get($action.'/'.$param1.'/'.$param2);
if ($rows==null)
{// no el tenim a cache
$rows=parent::get_data($sql);
$mc->set($action.'/'.$param1.'/'.$param2, $rows, 1, 3600);
}
}
else
{// no tenim memcached
$rows=parent::get_data($sql);
}

return $rows;
}

function get_last_in_category($id, $num=16, $offset=1)
{
$sql = "SELECT v.*
, p.title portal_title
, p.url portal_url
, p.id portal_id
FROM ep_portals p
, ep_videos v
, ep_categories_videos cv
WHERE cv.video_id = v.id
AND cv.category_id = ".$id."
AND v.status='O'
AND v.portal_id = p.id
ORDER BY v.added DESC
LIMIT ".(($offset-1)*$num).", ".$num;

$action='category';
$param1=$id;
$param2=$offset;
$mc=new Memcache;
$cr=$mc->connect('localhost', 11211);
if ($cr)
{// tenim memcached
$rows=$mc->get($action.'/'.$param1.'/'.$param2);
if ($rows==null)
{// no el tenim a cache
$rows=parent::get_data($sql);
$mc->set($action.'/'.$param1.'/'.$param2, $rows, 1, 3600);
}
}
else
{// no tenim memcached
$rows=parent::get_data($sql);
}

return $rows;

//return parent::get_data($sql);
}

function get_last_in_tag($id, $num=16, $offset=1)
{
$sql = "SELECT v.*
, p.title portal_title
, p.url portal_url
, p.id portal_id
FROM ep_portals p
, ep_videos v
, ep_tags_videos cv
WHERE cv.video_id = v.id
AND cv.tag_id = ".$id."
AND v.status='O'
AND v.portal_id=p.id
ORDER BY v.added DESC
LIMIT ".(($offset-1)*$num).", ".$num;

$action='tag';
$param1=$id;
$param2=$offset;
$mc=new Memcache;
$cr=$mc->connect('localhost', 11211);
if ($cr)
{// tenim memcached
$rows=$mc->get($action.'/'.$param1.'/'.$param2);
if ($rows==null)
{// no el tenim a cache
$rows=parent::get_data($sql);
$mc->set($action.'/'.$param1.'/'.$param2, $rows, 1, 3600);
}
}
else
{// no tenim memcached
$rows=parent::get_data($sql);
}

return $rows;

//return parent::get_data($sql);
}