dilluns, 21 de març del 2011

Accessos 60 cops més ràpids i àgils amb Shared Memory Functions

Les funcions de memòria compartida que suporta el PHP són una bona manera de gestionar indicadors de les aplicacions a nivell de sistema.

Es tracta d'una manera de tenir variables superglobals, és a dir, consultables per tots els scripts de l'aplicació. Realment el que estem fent és accedir directament a blocs de memòria del servidor, convenientment reservat i assegurat.

L'alternativa a aquesta gestió d'indicadors en memòria compartida són els tradicionals accessos al filesystem amb arxius semàfors.

Però si la gestió d'aquesta memòria ens resulta fartosa, sobretot per haver de fer sempre un shmop_read() i controlar l'error per saber si una posició està ocupada o lliure, si el PHP s'executa en un servidor Linux, podem fer servir les funcions semàfor que faciliten la programació amb aquesta tècnica.

shm_attach
La instrucció shm_attach ens permet tractar els segments de memòria amb una facilitat tant gran que a cops sembla que estiguem tractant amb arxius tipus semàfor.

Per reservar un segment executarem:
$this->seg = \shm_attach(0xCAFE, 1024, 0750);

El primer paràmetre és l'id de segment de memòria amb el que volem treballar. En aquest exemple fem servir un de proves, però en explotació podríem fer servir la funció ftok(__FILE__), si aquest segment el reservem per a tota l'aplicació des d'un únic arxiu, o ftok('/etc/app/myapp.ini') on indiquem la ruta de l'arxiu que conté la configuració per a l'aplicació i que s'estima únic per a la mateixa aplicació.

El segon paràmetre és la mida en bytes d'aquest segment, reservem un KB. Cal tenir en compte a l'hora de dimensionar segments, que PHP a hores d'ara encara no és un llenguatge nativament UTF-8.

El tercer paràmetre estableix els permisos d'aquest segment en format octal. Per omissió és 0666, però com que no volem que cap altre usuari del sistema que no sigui l'Apache, els del seu grup puguin llegir-ho, però la resta ni pugui conèixer la seva existència, establim permisos 0750.

shm_put_var
La instrucció shm_put_var serveix per a establir un valor a un slot del segment reservat.
\shm_put_var($this->seg, (int) $clau, $valor);

El primer paràmetre és l'id del segment.

El segon, l'slot del segment que volem declarar.

El tercer, és el valor pròpiament dit.


shm_get_var
La instruccio shm_get_var serveix per a recuperar un valor d'un slot del segment reservat.
if (\shm_has_var($this->seg, $clau))
{
return \shm_get_var($this->seg, (int) $clau);
}


El primer paràmetre és l'id del segment.

El segon, l'slot del segment que volem recuperar. Podem fer servir shm_has_var per tractar d'esbrinar prèviament si està declarat o no aquest slot.

Benchmark
Les proves de rendiment que hem fet comparant aquesta tècnica amb accessos a arxius tipus semàfor al filesystem ens han reportat una mitjana de 60 cops més ràpid l'accés a memòria compartida, que a arxius del filesystem tant per a l'establiment de variables, com per a la recuperació d'aquestes.

Una dada a tenir en compte!