Memcached es un almacén de clave-valor en memoria RAM pensado para una sola cosa: guardar resultados costosos de calcular (consultas a base de datos, fragmentos HTML, respuestas de APIs) y devolverlos en microsegundos. No persiste nada en disco ni tiene replicación, así que solo debe contener datos que la aplicación pueda regenerar. En este tutorial instalarás Memcached en Ubuntu 24.04, ajustarás su configuración, lo protegerás frente a accesos externos y lo usarás desde PHP y Python, incluido el almacenamiento de sesiones PHP.
Requisitos previos
Para seguir esta guía necesitas:
- Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath.
- Un usuario no root con privilegios
sudo. - Memoria libre suficiente para la caché que quieras reservar (64 MB bastan para probar; en producción es habitual dedicar entre 256 MB y varios GB).
- Opcional: PHP 8.3 con PHP-FPM o Python 3 si vas a seguir los ejemplos de integración.
Paso 1: Instalar Memcached
El paquete memcached contiene el servidor y libmemcached-tools añade utilidades de línea de comandos como memcstat para consultar estadísticas:
sudo apt update
sudo apt install memcached libmemcached-tools
El servicio se arranca y se habilita automáticamente. Compruébalo:
sudo systemctl status memcached
● memcached.service - memcached daemon
Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: enabled)
Active: active (running) since ...
Verifica que escucha solo en la interfaz local, en el puerto 11211:
sudo ss -tlnp | grep 11211
LISTEN 0 1024 127.0.0.1:11211 0.0.0.0:* users:(("memcached",pid=2481,fd=26))
LISTEN 0 1024 [::1]:11211 [::]:* users:(("memcached",pid=2481,fd=27))
Paso 2: Ajustar la configuración
Toda la configuración está en /etc/memcached.conf, un fichero con una opción de línea de comandos por línea. Ábrelo:
sudo nano /etc/memcached.conf
Estas son las líneas relevantes. Deja el resto como está:
# Memoria máxima para datos, en MB
-m 512
# Puerto TCP
-p 11211
# Usuario sin privilegios con el que se ejecuta
-u memcache
# Escuchar solo en localhost (IPv4 e IPv6)
-l 127.0.0.1
-l ::1
# Número máximo de conexiones simultáneas
-c 2048
# Hilos de trabajo (normalmente, el número de núcleos)
-t 4
-P /var/run/memcached/memcached.pid
Qué hace cada valor:
-m: límite de memoria para los datos. Cuando se llena, Memcached expulsa las claves menos usadas recientemente (LRU); no falla. Reserva un tamaño que el servidor pueda dedicar sin entrar en swap, porque una caché en swap es más lenta que no tener caché.-c: conexiones simultáneas. El valor por defecto es 1024. Súbelo si tienes muchos workers de PHP-FPM o de aplicación conectando a la vez.-t: hilos de trabajo. Por defecto son 4; ajústalo al número de núcleos que quieras dedicarle.-l: direcciones en las que escucha. Mantener127.0.0.1y::1es lo más seguro cuando la aplicación está en el mismo servidor.
Reinicia el servicio para aplicar los cambios:
sudo systemctl restart memcached
Comprueba que el nuevo límite de memoria está activo. limit_maxbytes se expresa en bytes (512 MB = 536870912):
memcstat --servers=127.0.0.1 | grep -E '^\s*(max_connections|limit_maxbytes|threads):'
max_connections: 2048
limit_maxbytes: 536870912
threads: 4
Paso 3: Probar el servidor a mano
Memcached usa un protocolo de texto, así que puedes hablar con él con nc. Guarda la clave prueba con el valor hola, una caducidad de 60 segundos y léela:
printf 'set prueba 0 60 4\r\nhola\r\nget prueba\r\nquit\r\n' | nc 127.0.0.1 11211
STORED
VALUE prueba 0 4
hola
END
El formato de set es set <clave> <flags> <segundos> <bytes>, seguido del valor en la línea siguiente. Si el tamaño en bytes no coincide con el valor, el servidor responde CLIENT_ERROR bad data chunk.
Paso 4: Proteger Memcached
Memcached no tiene autenticación por defecto. Un Memcached expuesto a Internet permite a cualquiera leer y borrar tu caché, y además se ha usado históricamente para ataques de amplificación. En Ubuntu 24.04 el protocolo UDP ya viene desactivado y el servicio escucha solo en localhost, así que si la aplicación está en el mismo servidor no tienes que hacer nada más.
Si la aplicación está en otro servidor, haz que Memcached escuche en la IP privada y limita el acceso con el cortafuegos. Edita /etc/memcached.conf y sustituye las líneas -l por la IP privada del servidor (your_private_ip):
-l your_private_ip
Reinicia el servicio y permite el puerto 11211 solo desde la IP del servidor de aplicación (your_app_server_ip):
sudo systemctl restart memcached
sudo ufw allow from your_app_server_ip to any port 11211 proto tcp
sudo ufw status
To Action From
-- ------ ----
11211/tcp ALLOW your_app_server_ip
Importantenunca uses
-l 0.0.0.0en un servidor con IP pública sin una regla de cortafuegos que restrinja el origen.
Paso 5: Usar Memcached desde PHP
La extensión recomendada es memcached (con "d"), basada en libmemcached. Instálala y recarga PHP-FPM:
sudo apt install php8.3-memcached
sudo systemctl reload php8.3-fpm
php -m | grep memcached
memcached
El patrón habitual es cache-aside: se busca la clave en Memcached y, si no está, se calcula el valor, se guarda con una caducidad y se devuelve. Crea un script de prueba:
nano ~/memcached-test.php
<?php
$mc = new Memcached();
$mc->addServer('127.0.0.1', 11211);
function obtenerProducto(Memcached $mc, int $id): array
{
$clave = "producto:$id";
$producto = $mc->get($clave);
if ($mc->getResultCode() === Memcached::RES_NOTFOUND) {
// Aquí iría la consulta real a la base de datos
$producto = ['id' => $id, 'nombre' => 'Ejemplo', 'generado' => date('H:i:s')];
$mc->set($clave, $producto, 300); // 5 minutos
echo "MISS: guardado en caché\n";
} else {
echo "HIT: leído de caché\n";
}
return $producto;
}
print_r(obtenerProducto($mc, 42));
print_r(obtenerProducto($mc, 42));
Ejecútalo:
php ~/memcached-test.php
MISS: guardado en caché
Array
(
[id] => 42
[nombre] => Ejemplo
[generado] => 10:15:02
)
HIT: leído de caché
Array
(
[id] => 42
[nombre] => Ejemplo
[generado] => 10:15:02
)
Cuando el dato cambia en la base de datos, invalida la clave con $mc->delete("producto:$id") para que la siguiente lectura la regenere.
Guardar las sesiones PHP en Memcached
Guardar las sesiones en Memcached permite compartirlas entre varios servidores web. Crea un fichero de configuración para PHP-FPM:
sudo nano /etc/php/8.3/fpm/conf.d/30-sesiones-memcached.ini
session.save_handler = memcached
session.save_path = "127.0.0.1:11211"
Recarga PHP-FPM y comprueba el valor desde una página PHP con phpinfo() o con php-fpm8.3 -i:
sudo systemctl reload php8.3-fpm
sudo php-fpm8.3 -i | grep -E '^session.save_(handler|path)'
session.save_handler => memcached => memcached
session.save_path => 127.0.0.1:11211 => 127.0.0.1:11211
Ten en cuenta que Memcached puede expulsar claves cuando se llena o al reiniciarse, lo que cerraría sesiones de usuario. Si eso no es aceptable, reserva memoria de sobra o usa Redis con persistencia para las sesiones.
Paso 6: Usar Memcached desde Python
Para Python, pymemcache es un cliente puro y bien mantenido. Instálalo en un entorno virtual:
sudo apt install python3-venv
python3 -m venv ~/mc-venv
~/mc-venv/bin/pip install pymemcache
Crea un script de prueba:
nano ~/memcached_test.py
from pymemcache.client.base import Client
from pymemcache import serde
client = Client(("127.0.0.1", 11211), serde=serde.pickle_serde)
client.set("usuario:7", {"nombre": "Ana", "plan": "pro"}, expire=300)
print(client.get("usuario:7"))
Ejecútalo:
~/mc-venv/bin/python ~/memcached_test.py
{'nombre': 'Ana', 'plan': 'pro'}
serde.pickle_serde serializa objetos de Python automáticamente. Sin él solo puedes guardar cadenas y bytes.
Paso 7: Supervisar el uso de la caché
Las estadísticas de Memcached indican si la caché está sirviendo de algo. Consulta las más útiles:
memcstat --servers=127.0.0.1 | grep -E '^\s*(curr_connections|get_hits|get_misses|bytes|curr_items|evictions):'
curr_connections: 3
get_hits: 18234
get_misses: 1022
bytes: 3129856
curr_items: 4410
evictions: 0
Cómo interpretarlas:
- Tasa de aciertos =
get_hits / (get_hits + get_misses). En el ejemplo es del 94 %. Si es baja, revisa las caducidades o qué datos estás cacheando. evictionscreciendo de forma constante significa que falta memoria: sube el valor de-m.curr_connectionscerca del valor de-cindica que debes subir el límite de conexiones.
Si necesitas vaciar la caché completa (por ejemplo, tras un despliegue que cambia el formato de los datos), usa:
memcflush --servers=127.0.0.1
Solución de problemas
- La aplicación no conecta (
Connection refused): comprueba consudo ss -tlnp | grep 11211en qué IP escucha el servicio y que coincide con la que usa la aplicación. Si es remota, revisa la regla de UFW. - El servicio no arranca tras editar la configuración: consulta
sudo journalctl -u memcached -n 50. Un error típico es una IP en-lque no existe en el servidor. - Los objetos grandes no se guardan: el tamaño máximo por elemento es 1 MB por defecto. Puedes subirlo con
-I 2men/etc/memcached.conf, aunque normalmente es mejor no cachear objetos tan grandes.
Conclusión
Ya tienes Memcached instalado en Ubuntu 24.04, limitado a la memoria que has decidido, protegido frente a accesos externos y conectado a PHP y Python, con las estadísticas necesarias para saber si la caché es eficaz. Como siguientes pasos, puedes activar OPcache para acelerar la ejecución de PHP, ajustar los pools de PHP-FPM o medir la mejora con Apache Bench antes y después de introducir la caché.
