
🌐 También en: English · Deutsch · Français
Deep Dive de la serie en torno al Ansible Tour. Nivel: administración Linux avanzada. El tour explica los roles; los deep dives explican la técnica que hay debajo – cómo funciona, por qué está aquí, qué hace exactamente esta instalación con ella, cómo operarla en el día a día y qué otras opciones habría habido.
Redis es el servicio más pequeño de esta instalación – unos pocos megabytes de memoria, una fracción de un núcleo – y las dos aplicaciones dependen de él. El blog lo usa como caché de objetos (parte 3), Nextcloud para el bloqueo de ficheros y como caché compartida entre procesos (parte 4). Este artículo explica qué hace Redis ahí, por qué las dos instancias se protegen de forma distinta, qué dicen las cifras y qué sacó a la luz una revisión para este artículo.
🧭 Cómo funciona Redis
Un hilo, todo en memoria
Redis guarda todos los datos en RAM y ejecuta los comandos uno tras otro en un único bucle de eventos. Suena a cuello de botella y es lo contrario: no hay bloqueos entre hilos, cada comando es atómico y una lectura sencilla tarda microsegundos. La red y las llamadas al sistema cuestan más que el propio comando.
Claves, tipos, caducidad
Cada entrada es una clave con un valor – una cadena, un hash, una lista, un conjunto. Cada clave puede llevar un tiempo de vida; Redis la borra cuando caduca. Las dos aplicaciones ponen tiempo de vida a casi todas las claves, así que el conjunto de datos se limpia solo.
Cuando se acaba la memoria
maxmemory fija un límite; maxmemory-policy decide qué ocurre al llegar a él. allkeys-lru expulsa la clave usada hace más tiempo – correcto para una caché pura, donde cada entrada se puede reconstruir. noeviction rechaza en cambio las nuevas escrituras – correcto para datos que no deben desaparecer sin aviso, como un bloqueo.
Persistencia – o ninguna
Redis puede escribir instantáneas (RDB, controladas por save) y un registro de todas las escrituras (AOF). Ambas sirven para datos que deben sobrevivir a un reinicio. Una caché y unos bloqueos de vida corta no necesitan ninguna: tras un reinicio la caché se vuelve a llenar y las aplicaciones toman bloqueos nuevos.
Autenticación y protected mode
requirepass (o, desde Redis 6, usuarios ACL) obliga a cada cliente a autenticarse primero. El protected mode solo rechaza conexiones externas si Redis escucha en todas las interfaces sin contraseña – en cuanto hay una dirección de escucha configurada y ninguna contraseña, ya no ayuda.
🛡️ Por qué está aquí
- Caché de objetos de WordPress. WordPress pide a la base de datos las mismas opciones, menús y metadatos de entradas en cada petición. Con el plugin Redis Object Cache, las respuestas salen de Redis.
- Bloqueo de ficheros de Nextcloud. Cuando dos clientes escriben el mismo fichero a la vez, Nextcloud necesita un bloqueo que cada proceso PHP, en cada pod, vea al instante. Sin él, los clientes de sincronización se sobrescriben entre sí. Nextcloud recomienda expresamente Redis para esto.
- Caché distribuida de Nextcloud. Los datos compartidos entre procesos – configuración de apps, estado cercano a la sesión – también están ahí; la caché por proceso es APCu.
🔧 Qué hace este repositorio
| Blog | Servidores Nextcloud | |
|---|---|---|
| Dónde | Pod en K3s (redis:7.4-alpine) | En el host, paquete de AlmaLinux (Redis 6.2) |
| Rol | blog_k3s_deploy | next_packages + next_redis |
| Se usa para | Caché de objetos | Bloqueo de ficheros + caché distribuida |
| Límite de memoria | 80 MB, allkeys-lru | ninguno, noeviction |
| Persistencia | ninguna (--save "", AOF desactivado) | instantáneas RDB (valor del paquete) |
| Contraseña | ninguna | requirepass del vault |
| Accesible por | Service ClusterIP, NetworkPolicy: solo los pods de WordPress | IP del nodo y 127.0.0.1, nftables: solo la red de pods |
| SELinux | container_t con categorías MCS propias | redis_t |
El blog: una caché desechable en un pod cerrado
command: ["redis-server", "--save", "", "--appendonly", "no",
"--maxmemory", "80mb", "--maxmemory-policy", "allkeys-lru"]
securityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
capabilities: { drop: [ALL] }Todo lo que hay en este Redis se puede tirar, y así está configurado: ninguna escritura en disco, un techo de memoria con expulsión LRU, un sistema de ficheros raíz de solo lectura, ninguna capability. No tiene contraseña porque nada fuera de la red de pods puede alcanzarlo y dentro solo pueden los pods de WordPress – una NetworkPolicy deniega cualquier otro pod, incluidos la base de datos y el ingress controller.
Nextcloud: por qué la contraseña
En los servidores Nextcloud, Redis corre en el host y los pods llegan a él a través de un Service de Kubernetes que apunta a la IP del nodo. Es decir, Redis escucha en la dirección pública del servidor. Entre Internet y Redis había, al principio, exactamente una regla de nftables. El rol next_redis añade requirepass como segunda capa, porque una regla que falla en silencio no es hipotética aquí: fail2ban estuvo muerto dos días en el blog sin que nadie lo notara. La contraseña llega a Nextcloud mediante un Secret de Kubernetes montado como redis.config.php – no mediante el ConfigMap que contiene el resto de la configuración, porque los ConfigMaps no están pensados para secretos.
- name: Redis | Ensure Redis requires authentication
ansible.builtin.lineinfile:
path: /etc/redis/redis.conf
regexp: '^requirepass\s+'
line: 'requirepass {{ nextcloud_redis_pass }}'
no_log: true # the line contains the password
notify: Restart Redis
- ansible.builtin.meta: flush_handlers # restart NOW, the next role needs itEl flush_handlers no es decorativo: los roles siguientes ejecutan comandos occ en el pod, que se conectan a Redis por la IP del nodo. Sin el reinicio inmediato, Redis seguiría escuchando solo en 127.0.0.1 en ese momento.
noeviction a propósito
El Redis del host no tiene límite de memoria y mantiene la política por defecto noeviction. Para bloqueos es lo correcto: un bloqueo expulsado sería un bloqueo que ha dejado de proteger un fichero sin avisar. De todos modos el conjunto de datos es diminuto (ver abajo) y el servidor tiene memoria de sobra.
📊 Medido
| Blog | Nextcloud A | Nextcloud B | |
|---|---|---|---|
| Versión | 7.4.11 | 6.2.24 | 6.2.24 |
| Memoria usada | 14,8 MB | 1,7 MB | 1,3 MB |
| Claves | 19.079 | 56 | 83 |
| Tasa de aciertos desde el reinicio | 87,6 % | 85,9 % | 64,4 % |
| Claves expulsadas | 0 | 0 | 0 |
| Entradas en el slow log | 1 | 3 | 0 |
Las dos cargas no se parecen en nada. La caché del blog contiene decenas de miles de objetos pequeños; Nextcloud, unas pocas docenas de bloqueos y entradas de caché que nacen y caducan sin parar – más de 11.000 claves caducaron en un día en el servidor mayor. La tasa de aciertos más baja del servidor Nextcloud pequeño es propia del bloqueo, no un problema: «¿está bloqueado este fichero?» es un fallo siempre que la respuesta es «no». La relación de fragmentación que Redis muestra para las instancias del host (de 7 a 9) parece alarmante y no significa nada a este tamaño – unos pocos megabytes de sobrecarga del proceso divididos entre uno o dos megabytes de datos.
El blog usa Predis, un cliente escrito en PHP, porque la imagen oficial de WordPress no incluye la extensión phpredis. La extensión en C sería más rápida; con un 88 % de aciertos y una caché de páginas delante, la diferencia no se nota en los tiempos de respuesta.
🔍 Qué encontró la revisión para este artículo
Al reunir los datos para este artículo aparecieron cuatro cosas que la instalación aún no hacía – ninguna peligrosa, todas dignas de saberse. Las cuatro están corregidas desde el 20 de octubre de 2026.
- Ninguna sandbox de systemd para el Redis del host. MariaDB en los mismos servidores recibió un drop-in de endurecimiento (ninguna capability, sistema de ficheros de solo lectura, filtro de llamadas al sistema); Redis corre solo con la unidad del paquete. SELinux lo confina de todos modos en
redis_t, así que no está desprotegido – pero falta la segunda capa que tiene MariaDB. El esquema de este mismo artículo afirmaba que existía. Corregido: el mismo tipo de drop-in que para MariaDB, con una trampa por el camino: las opciones de la sandbox implicanNoNewPrivileges, y con ello SELinux rechazó el paso aredis_t; Redis no arrancó durante dos minutos. Un pequeño módulo local (init_nnp_daemon_domain(redis_t)) permite exactamente esa transición. - Instantáneas que nadie necesita. El Redis del host mantiene el valor del paquete
save 3600 1 300 100 60 10000y escribedump.rdbcon regularidad – para bloqueos con tiempo de vida y una caché que se reconstruye sola. Restaurados tras un reinicio, los bloqueos obsoletos tendrían incluso que caducar primero. Corregido:save "", como en el blog, y el antiguodump.rdbeliminado. - Una contraseña cambiada no habría llegado a Nextcloud. Los datos de conexión vienen de un Secret montado con
subPath– y un montaje subPath nunca se actualiza en un pod en marcha. El pod se vuelve a desplegar cuando cambia su configuración, mediante una anotación con una suma de comprobación, pero el Secret no formaba parte de esa suma. Cambiar la contraseña habría reiniciado Redis con la nueva mientras Nextcloud conservaba la antigua hasta su siguiente reinicio casual: sin bloqueos, páginas de error. Corregido: el Secret forma parte ahora de la suma de comprobación. La última parte manual también está automatizada: el demonio de push notify_push lee la contraseña deconfig.php, donde el instalador la escribió una vez, y el playbook la copia ahí desde el Secret en cuanto difieren. - Monit no lo vigila. Monit reinicia y avisa de K3s, sshd y los servicios de monitorización, pero no del Redis ni del MariaDB del host en los servidores Nextcloud. Si Redis se parase, Nextcloud lo notaría primero y Grafana después. Corregido: ambos están ahora en la lista de Monit.
🧰 Operación diaria
# host (Nextcloud): password from the config, never on the command line
export REDISCLI_AUTH="$(awk '/^requirepass/{print $2}' /etc/redis/redis.conf)"
redis-cli INFO stats | grep -E 'keyspace_(hits|misses)|evicted'
redis-cli INFO memory | grep used_memory_human
redis-cli SLOWLOG GET 5
redis-cli --latency # Ctrl-C to stop
# blog pod
k3s kubectl -n wordpress exec deploy/redis -- redis-cli INFO keyspace
wp redis status # inside the WordPress container, as www-dataMONITORmuestra cada comando en directo – útil durante unos segundos, caro y lleno de datos en una instancia con carga.- Vaciar. En el blog,
wp cache flushvacía la caché de objetos sin riesgo. En Nextcloud, unFLUSHALLelimina también todos los bloqueos; solo en modo mantenimiento. - Cambiar la contraseña. Modificarla en el vault y ejecutar el playbook:
next_redisla escribe enredis.confy reinicia Redis,next_k3s_deployactualiza el Secret y – desde la corrección de arriba – vuelve a desplegar el pod de Nextcloud en la misma ejecución. notify_push la recibe en la misma ejecución. - Actualizaciones. El paquete del host recibe correcciones de seguridad mediante dnf-automatic, que después reinicia Redis; la imagen del blog sigue el pin de
versions.yml.
🆘 Chuleta: síntoma → comando
La versión corta de este artículo para el momento en que algo va mal. Ejecutar en el host como root; <…> son marcadores. occ y wp son las funciones de shell de los deep dives de Nextcloud y WordPress.
| Síntoma | Comando |
|---|---|
| ¿Está en marcha, y confinado? | systemctl status redis |
| Hablarle sin contraseña en la línea de comandos | export REDISCLI_AUTH="$(awk '/^requirepass/{print $2}' /etc/redis/redis.conf)" |
| ¿Hace su trabajo la caché? | redis-cli INFO stats | grep -E 'keyspace_(hits|misses)|evicted' |
| ¿Memoria llena? | redis-cli INFO memory | grep -E "used_memory_human|maxmemory_human" |
| Comandos lentos, latencia alta | redis-cli SLOWLOG GET 5 |
| Sin notificaciones push en Nextcloud | k3s kubectl -n nextcloud logs deploy/notify-push --tail=20 |
| La caché del blog | k3s kubectl -n wordpress exec deploy/redis -- redis-cli INFO keyspace |
🔭 Lo que viene
- Valkey. Después de que Redis cambiara su licencia en 2024, el fork Valkey de la Linux Foundation pasó a ser el predeterminado en varias distribuciones. Es un sustituto directo; cambiar sería una modificación de paquete o de imagen.
- Métricas. Un redis_exporter llevaría la tasa de aciertos y la memoria a Grafana en lugar de un
INFOmanual.
⚖️ Alternativas – y por qué Redis
| Opción | Punto fuerte | Por qué no aquí |
|---|---|---|
| Memcached | Caché sencilla y rápida | Sin semántica de bloqueo que Nextcloud pueda usar; el bloqueo se quedaría en la base de datos. |
| Solo APCu | En el proceso, sin red | No se comparte entre procesos PHP ni pods – inútil para bloqueos. Nextcloud la usa además como caché local. |
| Bloqueo en la base de datos | Ningún servicio adicional | La alternativa de reserva de Nextcloud; carga el componente más ocupado y es más lenta. |
| Valkey / KeyDB | Forks con otra gobernanza u otro modelo de hilos | Valkey es el probable siguiente paso; KeyDB está menos activo. |
| Redis | Lo que ambas aplicaciones esperan y prueban, huella diminuta | Elegido. |
Redis es el tipo de componente que se olvida fácilmente porque nunca se queja. La revisión para este artículo recordó que «funciona» y «está configurado como el resto» son dos afirmaciones distintas – y que la segunda merece comprobarse también en los servicios pequeños.


