← Volver al listado de tecnologías
Clustering en Valkey
Clustering
¿Por qué Cluster?
- Escalabilidad horizontal: Más nodos = más capacidad
- Alta disponibilidad: Failover automático
- Distribución de carga: Datos repartidos entre nodos
Arquitectura del Cluster
┌─────────────────────────────────────────────────┐
│ Hash Slots │
│ (16384 slots totales) │
├─────────────┬─────────────┬─────────────────────┤
│ 0-5460 │ 5461-10922 │ 10923-16383 │
│ Nodo A │ Nodo B │ Nodo C │
│ + Replica │ + Replica │ + Replica │
└─────────────┴─────────────┴─────────────────────┘
Cada clave se mapea a un slot: HASH_SLOT = CRC16(key) mod 16384
Configuración mínima
Crear nodos del cluster
# Crear directorios para cada nodo
mkdir -p cluster/{7000,7001,7002,7003,7004,7005}
# Configuración base para cada nodo
cat > cluster/7000/valkey.conf << EOF
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
appendfilename "appendonly.aof"
dir ./
EOF
# Copiar y ajustar puerto para cada nodo
for port in 7001 7002 7003 7004 7005; do
sed "s/7000/$port/g" cluster/7000/valkey.conf > cluster/$port/valkey.conf
done
Iniciar nodos
# Iniciar cada nodo
for port in 7000 7001 7002 7003 7004 7005; do
cd cluster/$port && valkey-server valkey.conf &
cd ../..
done
Crear el cluster
valkey-cli --cluster create \
127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \
127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1
Docker Compose
# docker-compose.yml
services:
node1:
image: valkey/valkey:latest
ports:
- "7000:7000"
- "17000:17000"
command: valkey-server --port 7000 --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000 --appendonly yes
volumes:
- ./data/7000:/data
node2:
image: valkey/valkey:latest
ports:
- "7001:7001"
- "17001:17001"
command: valkey-server --port 7001 --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000 --appendonly yes
volumes:
- ./data/7001:/data
node3:
image: valkey/valkey:latest
ports:
- "7002:7002"
- "17002:17002"
command: valkey-server --port 7002 --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000 --appendonly yes
volumes:
- ./data/7002:/data
Comandos de cluster
# Conectar a un nodo
valkey-cli -c -p 7000
# Info del cluster
CLUSTER INFO
# Nodos del cluster
CLUSTER NODES
# Slots asignados
CLUSTER SLOTS
# Qué nodo tiene una clave
CLUSTER KEYSLOT mi_clave
# (integer) 12539
# Contar claves en un slot
CLUSTER COUNTKEYSINSLOT 12539
Operaciones con claves
# El cliente redirige automáticamente con -c
valkey-cli -c -p 7000
SET usuario:1 "Juan"
# -> Redirected to slot [12182] located at 127.0.0.1:7002
GET usuario:1
# "Juan"
Hash Tags para colocación
# Claves con mismo hash tag van al mismo slot
SET {user:1}:perfil "datos"
SET {user:1}:sesiones "sesiones"
SET {user:1}:preferencias "prefs"
# Todas en el mismo slot (calculado sobre "user:1")
CLUSTER KEYSLOT {user:1}:perfil
CLUSTER KEYSLOT {user:1}:sesiones
# Mismo resultado
Gestión del cluster
Añadir nodo
# Añadir como master vacío
valkey-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000
# Añadir como réplica
valkey-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7000 \
--cluster-slave --cluster-master-id <node-id>
Rebalancear slots
# Redistribuir slots equitativamente
valkey-cli --cluster rebalance 127.0.0.1:7000
# Mover slots específicos
valkey-cli --cluster reshard 127.0.0.1:7000 \
--cluster-from <source-node-id> \
--cluster-to <target-node-id> \
--cluster-slots 1000
Eliminar nodo
# Primero mover sus slots
valkey-cli --cluster reshard 127.0.0.1:7000
# Luego eliminar
valkey-cli --cluster del-node 127.0.0.1:7000 <node-id>
Failover
# Failover manual (ejecutar en réplica)
CLUSTER FAILOVER
# Forzar failover
CLUSTER FAILOVER FORCE
# Ver estado
CLUSTER INFO
# cluster_state:ok
Conexión desde aplicaciones
Python
from valkey.cluster import ValkeyCluster
rc = ValkeyCluster(
host='localhost',
port=7000,
decode_responses=True
)
rc.set('clave', 'valor')
valor = rc.get('clave')
# Operaciones multi-key (mismo slot)
rc.mset({'{user:1}:a': '1', '{user:1}:b': '2'})
Node.js
import { createCluster } from 'valkey';
const cluster = createCluster({
rootNodes: [
{ url: 'valkey://localhost:7000' },
{ url: 'valkey://localhost:7001' },
{ url: 'valkey://localhost:7002' }
]
});
await cluster.connect();
await cluster.set('clave', 'valor');
const valor = await cluster.get('clave');
Limitaciones del cluster
- Multi-key: Solo funciona si claves están en mismo slot
- Transacciones: Limitadas al mismo slot
- Pub/Sub: Mensajes se propagan a todos los nodos
- Lua scripts: Todas las claves deben estar en mismo slot
# Esto falla (diferentes slots)
MGET usuario:1 usuario:2 usuario:3
# Esto funciona (mismo slot con hash tag)
MGET {user}:1 {user}:2 {user}:3
Monitoreo
# Estado general
valkey-cli --cluster check 127.0.0.1:7000
# Info de cada nodo
valkey-cli --cluster info 127.0.0.1:7000
# Script de monitoreo
#!/bin/bash
for port in 7000 7001 7002; do
echo "=== Nodo $port ==="
valkey-cli -p $port CLUSTER INFO | grep -E "(state|slots|size)"
done
Ejercicios
- Crea un cluster de 6 nodos (3 masters + 3 réplicas)
- Implementa hash tags para agrupar datos de usuario
- Simula la caída de un master y verifica el failover
Resumen
- El cluster distribuye datos en 16384 hash slots
- Mínimo 3 masters para cluster funcional
- Hash tags
{...}controlan ubicación de claves --clusterpara gestión administrativa- Conexión con
-cpara redirección automática