¿Qué es Memcached?

Memcached es definido por Danga Interactive, la empresa que lo desarrollo y mantiene el proyecto bajo licencia BSD como un “sistema distribuido de alta performance para el cacheo de objetos en memoria, genérico por naturaleza, pero pensado para incrementar la velocidad de aplicaciones web dinámicas, aliviando la carga de las bases de datos”.

La idea es muy simple y a la vez muy efectiva: un servicio que escucha en un host y un port específico, que puede almacenar cadenas de bytes (strings). De esta manera, podríamos estar guardando en memoria una estructura serializada de PHP o Java, un string encodeado con Json, o un documento de cualquier formato (después de todo no dejan de ser cadenas de bytes).

Existe actualmente una implementacion de Memcached Server que corre en Win32. Si bien no es oficial, cuenta con el apoyo de varios desarrolladores de la comunidad.

Funcionamiento

A grandes rasgos, el Memcached Server almacena los strings (internamente denominados ítems), en una gran tabla de hash, y los mapea según la clave que le asociemos a dicho ítem.

Dicha tabla de hash adopta una estructura de porciones de memoria de tamaño variable (denominadas slabs), con el objetivo de optimizar la asignación del espacio de memoria.

Un dato no menor es el slab de mayor tamaño (1 Mb), siendo este por consiguiente el tamaño máximo que un ítem puede tener si quiere ser almacenado en Memcached Server (aunque este valor puede ser modificado desde el código fuente).

Su arquitectura escalable nos permite mantener un pool de Memcached servers, característica que bien puede ser explotada en momentos donde la cantidad de conexiones no puede ser gestionada por un único Server. En ese caso, el pool optará por otro Server, balanceando la carga de conexiones.

Protocolo

La comunicación de clientes con servidor es muy simple, y basada en comandos. El protocolo Memcached implementa 3 comandos de almacenamiento, con pequeñas diferencias en su funcionamiento:

  • SET: Actualiza el objeto si no existía anteriormente, o lo agrega en caso contrario.
  • ADD: Agrega el objeto solo si no existe.
  • REPLACE: Actualiza el objeto solo si existe.

Memcached permite controlar el tiempo de vida de un objeto, indicando el “tiempo de expiración” para el mismo, en el momento de realizar una operación de almacenamiento.

A su vez, posee un comando de recuperación: GET. Podemos eliminar un objeto mediante el comando DELETE. Además, el protocolo implementa comandos para recuperar estadísticas, vaciar el cache, utilizar algún tipo de compresión, entre otros.

Ejemplo de uso

<?php 

// Inicializamos y conectamos 
$memcache = new Memcache; 
$memcache->connect('localhost', 11211) or die("No podemos conectarnos"); 

// Creamos una estructura a cachear 
$pichongol = new stdClass; 
$pichongol->nombre = “Daniel”; 
$pichongol->apellido = “Lopez”; 

// Almacenamos la estructura con una expiracion de 10 segundos 
$memcache->set(“pichongol”, $pichongol, false, 10) or die ("No podemos guardar la estructura"); 

// Recuperamos la estructura 
$result = $memcache->get(“pichongol”); 
echo "Estructura recuperada:<br/>\n"; 
print_r($result); 
 
?>  

¿Quiénes usan Memcached?

El desarrollo inicial y sus posteriores mejoras nacen como una necesidad de incrementar velocidades de respuesta para las peticiones web, en sitios de tráfico masivo.

Actualmente, su uso continúa expandiéndose, a medida que el proyecto toma mayor fuerza con la ayuda de varios desarrolladores de la comunidad Open Source que revisan y agregan nuevas capacidades al proyecto.

La siguiente es una lista acotada de sitios que actualmente utilizan Memcached para resolver cuestiones de escalabilidad:

Memcached nace como un desarrollo para el backend de LiveJournal, y como tal, es el primer sitio que lo implementa.

Luego de tener ciertas falencias de performance (producto de tener que manejar en promedio, de 35 a 40 millones de page views diarios) implementaron Memcached, logrando una gran mejoría en la prestación del servicio.

Contribuyó al proyecto, aportando muchas mejoras relacionadas con el manejo de memoria y los algoritmos de hashing, principalmente. Es actualmente la mayor implementación conocida, compuesta de alrededor de 200 servers de 1GB de memoria cada uno.

Monitoreando su funcionamiento

En estado natural, a medida que el tiempo transcurre, se incrementa la cantidad de ítems almacenados:

imagen18.jpg

En el anterior ejemplo, podemos ver como la cantidad de ítems se va incrementando hasta la hora 8, momento en el cual se realizó un “restart” del Memcached Server. Luego de ese instante, los ítems vuelven a almacenarse progresivamente.

El “Hits Ratio” es el índice que nos indica la relacion de éxito entre las veces que solicitamos un ítem, y las veces que efectivamente esta cacheado y por ende recuperado.

Estadísticamente y dependiendo del proyecto, es muy comun que el Hits Ratio se ubique en la franja del 85% – 98%. Claramente podemos imaginarnos la mejora al rendimiento general que esto representa, si tenemos en cuenta la merma en la carga de las Bases de datos, así también el tiempo de respuesta de los web servers. El siguiente gráfico nos demuestra lo anteriormente dicho:
imagen21.jpg

Obviamente, en algún momento de “restart” del Memcached Server, todos los objetos cacheados se pierden, y por ende cae el Hit Ratio, para en poco tiempo ubicarse dentro de los niveles normales.

Conclusión

Memcached y escalabilidad van de la mano, y todos podemos sacar jugo de esta interesante herramienta. Nuevamente se demuestra que las ideas brillantes son simples por naturaleza.