Memcached

Memcached es un sistema distribuido de propósito general para caché basado en memoria, diseñado por Danga Interactive y que es muy usado en la actualidad por múltiples sitios web.

Memcached es empleado para el almacenamiento en caché de datos u objetos en la memoria RAM, reduciendo así las necesidades de acceso a un origen de datos externo (como una base de datos o una API). Memcached tiene versiones para Linux, Windows y MacOS y se distribuye bajo licencia de software libre permisiva.

Su funcionamiento se basa en una tabla hash distribuida a lo largo de varios equipos. Conforme ésta se va llenando, los datos que más tiempo llevan sin ser utilizados se borran para dar espacio a los nuevos. Normalmente, las aplicaciones comprueban primero si pueden acceder a los datos a través de Memcached antes de recurrir a un almacén de datos más lento, como puede ser una base de datos.

Este sistema es empleado por varios de los sitios más activos y visitados de la red, como YouTube, Reddit, Playdom, Zynga, Facebook
 y Twitter.  Heroku ofrece un servicio de Memcached gestionado con NorthScale como parte de su  PaaS.  Google App Engine ofrece también un servicio de memcached a través de un API.

Historia 
Memcached fue desarrollado inicialmente por Brad Fitzpatrick para su sitio web LiveJournal, el 22 de mayo de 2003.

Arquitectura 
El sistema usa una arquitectura cliente-servidor.  Los servidores mantienen un array asociativo clave-valor; los clientes añaden datos al array y acceden a él. Las claves pueden tener una longitud de hasta 250 bytes y los datos pueden tener un tamaño de hasta 1 megabyte.

Los clientes usan librerías cliente para acceder a los servidores que, por defecto, utilizan el puerto 11211 Cada cliente mantiene una lista de todos los servidores; los servidores no se comunican entre ellos. Si un cliente desea establecer o leer el valor correspondiente a cierta clave, la librería cliente primero hace un cálculo mediante un algoritmo hash para determinar el servidor que va a utilizar. Entonces se pone en contacto con el servidor y este usará otro hash para determinar dónde almacenar o leer el valor correspondiente.

El servidor mantiene los valores en RAM.  Si un servidor agota su memoria, descarta los valores más antiguos.  Por tanto, los clientes deben de tratar Memcached como una caché transitoria; no pueden asumir que los datos almacenados en Memcached estarán ahí cuando los necesiten.  Un producto compatible a nivel de protocolo con Memcached llamado MemcacheDB proporciona almacenamiento permanente.  Hay también una solución llamada Membase de Northscale que proporciona persistencia, replicación y clustering.

Para que un cliente pueda leer los datos almacenados por otro cliente, deberían ambos usar el mismo algoritmo hash para localizar los servidores.

Un despliegue típico tendría varios servidores y muchos clientes.  Sin embargo, es posible usar Memcached en un único ordenador, actuando simultáneamente como cliente y servidor.

Seguridad 

La mayor parte de los despliegues de Memcached se hacen en redes corporativas "de confianza", donde los clientes se pueden conectar libremente a cualquier servidor.  Hay casos, sin embargo, en los que Memcached es desplegado en redes inseguras o en las que los administradores querrían ejercer un control en la forma que se conectan los cliente.  Para este propósito Memcached puede ser compilado con el soporte opcional de autentificación SASL.  El soporte SASL requiere el uso del protocolo binario.

Código de ejemplo 

Tenga en cuenta que todas las funciones descritas en esta página son pseudocódigo.  Las llamadas a funciones Memcached pueden variar en función del lenguaje y la API usada.

Convertir un objeto de base de datos o consulta para que use Memcache es simple.  Lo típico, cuando se usan consultas a la base de datos, sería lo siguiente:

 function get_foo(int userid) {
    result = db_select("SELECT * FROM users WHERE userid = ?", userid);
    return result;
 }
Después de la conversión a Memcached, la misma llamada tendría el siguiente aspecto:
 function get_foo(int userid) {
     /* primero miramos en la cache */
     data = memcached_fetch("registro:" + userid);
     if (!data) {
         /* no se ha encontrado : se consulta la base de datos */
         data = db_select("SELECT * FROM users WHERE userid = ?", userid);
         /* almacenamos en la caché para la próxima */
         memcached_add("registro:" + userid,  data);
     }
     return data;
 }
El servidor debe chequear primero si existe un valor en Memcached con la clave única "registro:userid", en la que userid es un número. Si el resultado no existe, entonces haría  la consulta select a la base de datos, y establecería la clave única usando la función de la API de Memcached "add".

Además de la llamada a esta función, es necesario crear una función "set" para actualizar el dato después de una modificación del mismo en la base de datos, y así evitar tener en la caché datos "obsoletos".
 function update_foo(int userid, string dbUpdateString) {
     /* primero actualizamos la base de datos */
     result = db_execute(dbUpdateString);
     if (result) {
         /* actualización con éxito : cogemos los datos para almacenarlos en la caché */
         data = db_select("SELECT * FROM users WHERE userid = ?", userid);
         /* la última línea también podría ser data = createDataFromDBString(dbUpdateString);   */
         /* almacenamos en la caché para la próxima */
         memcached_set("registro:" + userid, data);
     }
 }
Esta llamada actualizará el dato actualmente almacenado en la caché con el nuevo dato de la base de datos, suponiendo que la consulta a la base se lleva a cabo con éxito. Otro opción sería invalidar la caché con la función de Memcached "delete", de forma que las siguientes consultas a la caché en busca de este dato fallen, y la base de datos sea consultada. Haría falta hacer algo similar cuando los registros de la base de datos sean borrados, para que los datos de la caché sean coherentes.

Véase también 
 Memcachedb
 Redis

Referencias

Enlaces externos 
 Sitio oficial de Memcached
 "memcachemanager", administrador de Memcached hecho en PHP y con soporte de etiquetas
 membase
 Memcached y Ruby

Distribuciones con soporte comercial 
 NorthScale Memcached Server (de uso gratuito, soporte disponible bajo suscripción)
 GigaSpaces Java based Memcached (edición "community" gratuita, con tolerancia a fallos)

Caché
Gestión de memoria
Software de 2003
Software multiplataforma