Redis Cluster reparte las claves entre varios primarios y mantiene réplicas de cada uno, de modo que puedes crecer más allá de la memoria de un solo servidor y seguir funcionando si cae un nodo. Cada clave pertenece a uno de los 16.384 hash slots y cada primario sirve un rango de slots. En este tutorial crearás en Ubuntu 24.04 un clúster con tres primarios y tres réplicas, comprobarás cómo se redirigen las claves, probarás un failover y añadirás un nodo nuevo moviendo slots en caliente.

Requisitos previos

Para seguir esta guía necesitas:

  • Seis servidores con Ubuntu 24.04 LTS, por ejemplo seis VPS de CubePath, en la misma red privada. Tres serán primarios y tres réplicas; 1 GB de RAM por nodo basta para las pruebas. En los ejemplos se usan las IP 10.0.0.11 a 10.0.0.16.
  • Un séptimo servidor (10.0.0.17) para el paso de ampliación, opcional.
  • Un usuario no root con privilegios sudo en cada servidor.

Tres primarios es el mínimo que admite Redis Cluster. Poner primario y réplica en servidores distintos es lo que permite sobrevivir a la caída de uno.

Si solo necesitas alta disponibilidad y tus datos caben en un servidor, Redis Sentinel es más sencillo: Redis Cluster obliga a que los clientes soporten el modo clúster y limita las operaciones con varias claves.

Paso 1: Instalar Redis en todos los nodos

Instala Redis 7.0 desde los repositorios de Ubuntu en los seis servidores:

sudo apt update
sudo apt install redis-server

Comprueba la versión:

redis-server --version
Redis server v=7.0.15 sha=00000000:0 malloc=jemalloc-5.3.0 bits=64 build=...

Paso 2: Activar el modo clúster

Genera una contraseña compartida para todo el clúster y guárdala en lugar seguro:

openssl rand -base64 32

En cada nodo, abre la configuración:

sudo nano /etc/redis/redis.conf

Modifica o añade estas directivas. En bind pon la IP privada de cada servidor y sustituye your_strong_password por la contraseña generada:

bind 127.0.0.1 -::1 10.0.0.11
requirepass your_strong_password
masterauth your_strong_password

cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 5000

appendonly yes
  • cluster-enabled yes arranca Redis en modo clúster.
  • cluster-config-file es un archivo que Redis gestiona solo (se guarda en /var/lib/redis) con el estado del clúster: nodos, slots y réplicas. No lo edites a mano.
  • cluster-node-timeout son los milisegundos sin respuesta tras los que un nodo se considera caído.
  • masterauth permite a las réplicas autenticarse contra su primario. Todos los nodos usan la misma contraseña.
  • appendonly yes activa la persistencia AOF para no perder las escrituras recientes si un nodo se reinicia.

Reinicia Redis y comprueba que está en modo clúster:

sudo systemctl restart redis-server
redis-cli -a 'your_strong_password' --no-auth-warning cluster info | head -1
cluster_state:fail

fail es lo esperado en este punto: el nodo está en modo clúster pero todavía no tiene slots asignados.

Paso 3: Abrir los puertos del clúster

Cada nodo usa dos puertos: 6379 para los clientes y 16379 (el puerto de datos más 10000) para el cluster bus, por donde los nodos intercambian estado y coordinan los failovers. Ábrelos solo a la red privada en los seis servidores:

sudo ufw allow from 10.0.0.0/24 to any port 6379 proto tcp
sudo ufw allow from 10.0.0.0/24 to any port 16379 proto tcp

Si UFW no estaba activo, permite antes SSH con sudo ufw allow OpenSSH y actívalo con sudo ufw enable. Comprueba desde un nodo que llegas al bus de otro:

nc -zv 10.0.0.12 16379
Connection to 10.0.0.12 16379 port [tcp/*] succeeded!

Paso 4: Crear el clúster

Desde cualquiera de los nodos, crea el clúster con redis-cli --cluster create. La opción --cluster-replicas 1 indica una réplica por primario, así que con seis nodos obtendrás tres primarios y tres réplicas:

redis-cli -a 'your_strong_password' --no-auth-warning --cluster create \
  10.0.0.11:6379 10.0.0.12:6379 10.0.0.13:6379 \
  10.0.0.14:6379 10.0.0.15:6379 10.0.0.16:6379 \
  --cluster-replicas 1

redis-cli propone un reparto de slots y pide confirmación:

>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 10.0.0.15:6379 to 10.0.0.11:6379
Adding replica 10.0.0.16:6379 to 10.0.0.12:6379
Adding replica 10.0.0.14:6379 to 10.0.0.13:6379
...
Can I set the above configuration? (type 'yes' to accept):

Escribe yes. Al terminar verás:

[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

Paso 5: Verificar el clúster

Comprueba el estado general:

redis-cli -a 'your_strong_password' --no-auth-warning cluster info | head -7
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3

Lista los nodos con su papel y sus slots:

redis-cli -a 'your_strong_password' --no-auth-warning cluster nodes
3f1c...a2 10.0.0.11:6379@16379 myself,master - 0 0 1 connected 0-5460
8b7e...d4 10.0.0.12:6379@16379 master - 0 1727260000000 2 connected 5461-10922
c02a...91 10.0.0.13:6379@16379 master - 0 1727260000000 3 connected 10923-16383
e5d9...07 10.0.0.15:6379@16379 slave 3f1c...a2 0 1727260000000 1 connected
...

La primera columna es el ID de cada nodo; lo necesitarás para algunas operaciones. Para una revisión completa de consistencia usa:

redis-cli -a 'your_strong_password' --no-auth-warning --cluster check 10.0.0.11:6379

Paso 6: Trabajar con claves en el clúster

Un cliente normal que pide una clave a un nodo que no la tiene recibe un error MOVED. redis-cli sigue esas redirecciones con la opción -c:

redis-cli -c -h 10.0.0.11 -a 'your_strong_password' --no-auth-warning

Dentro de la consola:

10.0.0.11:6379> set usuario:1000 "Ana"
-> Redirected to slot [7319] located at 10.0.0.12:6379
OK
10.0.0.12:6379> set usuario:2000 "Luis"
-> Redirected to slot [1867] located at 10.0.0.11:6379
OK
10.0.0.11:6379> cluster keyslot usuario:2000
(integer) 1867

El slot se calcula con CRC16 sobre el nombre de la clave, así que una misma clave cae siempre en el mismo slot. Las operaciones con varias claves (MGET, MSET, transacciones, scripts Lua) solo funcionan si todas las claves están en el mismo slot. Para forzarlo usa hash tags: si una clave contiene {...}, solo se usa lo que hay entre llaves para calcular el slot.

10.0.0.11:6379> mset {usuario:1000}:nombre "Ana" {usuario:1000}:email "[email protected]"
-> Redirected to slot [7319] located at 10.0.0.12:6379
OK
10.0.0.12:6379> mget {usuario:1000}:nombre {usuario:1000}:email
1) "Ana"
2) "[email protected]"

Sin hash tags, ese MSET fallaría con CROSSSLOT Keys in request don't hash to the same slot. No abuses de ellos: si demasiadas claves comparten tag, acaban todas en un solo nodo.

Sal con exit.

Paso 7: Probar el failover

Detén Redis en un primario, por ejemplo 10.0.0.12:

sudo systemctl stop redis-server

Tras el cluster-node-timeout (5 segundos) y unos segundos de votación, su réplica pasa a primario. Compruébalo desde otro nodo:

redis-cli -a 'your_strong_password' --no-auth-warning cluster nodes | grep master
3f1c...a2 10.0.0.11:6379@16379 myself,master - 0 0 1 connected 0-5460
8b7e...d4 10.0.0.12:6379@16379 master,fail - 1727260100000 1727260095000 2 disconnected
c02a...91 10.0.0.13:6379@16379 master - 0 1727260110000 3 connected 10923-16383
a71b...5e 10.0.0.16:6379@16379 master - 0 1727260110000 7 connected 5461-10922

La clave usuario:1000 sigue disponible, ahora servida por 10.0.0.16. Arranca de nuevo el nodo caído:

sudo systemctl start redis-server

Vuelve como réplica del nuevo primario. Si quieres devolverle el papel de primario, conéctate a él y ejecuta un failover manual, que cambia los papeles sin pérdida de datos:

redis-cli -h 10.0.0.12 -a 'your_strong_password' --no-auth-warning cluster failover
OK

Paso 8: Añadir un nodo y redistribuir slots

Para crecer, prepara un séptimo servidor (10.0.0.17) con los pasos 1 a 3. Después, desde cualquier nodo, únelo al clúster indicando el nuevo nodo y uno existente:

redis-cli -a 'your_strong_password' --no-auth-warning --cluster add-node 10.0.0.17:6379 10.0.0.11:6379
[OK] New node added correctly.

El nodo entra como primario vacío, sin slots. Reparte slots de los demás primarios hacia él. rebalance con --cluster-use-empty-masters calcula un reparto equilibrado y mueve las claves en caliente, sin cortar el servicio:

redis-cli -a 'your_strong_password' --no-auth-warning --cluster rebalance 10.0.0.11:6379 --cluster-use-empty-masters
>>> Rebalancing across 4 nodes. Total weight = 4.00
Moving 1366 slots from 10.0.0.11:6379 to 10.0.0.17:6379
...

Verifica con --cluster check: cada primario debe tener unos 4.096 slots. Para dar una réplica al nuevo primario, prepara otro servidor y añádelo con --cluster-slave:

redis-cli -a 'your_strong_password' --no-auth-warning --cluster add-node 10.0.0.18:6379 10.0.0.11:6379 \
  --cluster-slave --cluster-master-id <id_de_10.0.0.17>

Para retirar un primario, primero vacía sus slots con redis-cli --cluster reshard hacia otros nodos y después elimínalo con redis-cli --cluster del-node 10.0.0.11:6379 <id_del_nodo>. Un nodo con slots no se puede eliminar.

Paso 9: Conectar una aplicación

Los clientes deben soportar el modo clúster: leen el mapa de slots, envían cada comando al nodo correcto y actualizan el mapa cuando reciben MOVED. Con Python, redis-py lo incluye:

sudo apt install python3-redis
nano cluster_test.py
from redis.cluster import RedisCluster, ClusterNode

rc = RedisCluster(
    startup_nodes=[ClusterNode("10.0.0.11", 6379), ClusterNode("10.0.0.12", 6379)],
    password="your_strong_password",
)

rc.set("pedido:42", "pendiente")
print(rc.get("pedido:42"))
print("Slot:", rc.keyslot("pedido:42"))
python3 cluster_test.py
b'pendiente'
Slot: 2873

Da varios nodos en startup_nodes para que el cliente pueda arrancar aunque uno esté caído.

Solución de problemas

--cluster create se queda en Waiting for the cluster to join. Los nodos no alcanzan el cluster bus de los demás. Comprueba que el puerto 16379 está abierto entre todos y que bind incluye la IP privada.

[ERR] Node 10.0.0.x:6379 is not empty. El nodo ya tiene claves o conoce otro clúster. En un nodo de pruebas, vacíalo con redis-cli -a 'your_strong_password' flushall y redis-cli -a 'your_strong_password' cluster reset, que borran sus datos.

--cluster check avisa de slots abiertos (open slots). Un resharding se interrumpió. redis-cli --cluster fix 10.0.0.11:6379 los cierra.

Una réplica no se sincroniza y el log muestra errores de autenticación. masterauth falta o no coincide con requirepass. Revisa sudo journalctl -u redis-server y /var/log/redis/redis-server.log en ese nodo.

Conclusión

Has creado un Redis Cluster de tres primarios con una réplica cada uno, has visto cómo se reparten las claves por slots, has probado un failover y has ampliado el clúster moviendo slots en caliente. Como siguientes pasos, mide la memoria de cada nodo con INFO memory y define maxmemory y una política de expulsión, programa copias de los archivos RDB/AOF de /var/lib/redis y revisa que tu aplicación usa hash tags en las operaciones con varias claves.