TestForge Blog
← All Posts

Setting Up Redis Cluster — From 6-Node Configuration to Operations

Step-by-step guide to building a Redis Cluster from scratch. 6-node setup, slot distribution, client connections, and failover handling — all production-focused.

TestForge Team ·

Redis Cluster Fundamentals

16384 hash slots distributed across multiple Master nodes.

Master1: Slots 0 – 5460
Master2: Slots 5461 – 10922
Master3: Slots 10923 – 16383

Each Master has 1 Replica → minimum 6 nodes total

Slot for each key: HASH_SLOT = CRC16(key) % 16384

1. Installation and Node Configuration

Prepare 6 servers (or VMs/containers): ports 7001–7006

# redis-7001.conf (change port number for each node)
port 7001
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes-7001.conf
cluster-node-timeout 5000
appendonly yes
appendfsync everysec
maxmemory 4gb
maxmemory-policy allkeys-lru
protected-mode no
# Start each node
redis-server redis-7001.conf &
redis-server redis-7002.conf &
redis-server redis-7003.conf &
redis-server redis-7004.conf &
redis-server redis-7005.conf &
redis-server redis-7006.conf &

2. Create the Cluster

redis-cli --cluster create \
  192.168.1.1:7001 \
  192.168.1.2:7002 \
  192.168.1.3:7003 \
  192.168.1.4:7004 \
  192.168.1.5:7005 \
  192.168.1.6:7006 \
  --cluster-replicas 1

# First 3 → Masters, last 3 → one Replica each
# --cluster-replicas 1 = 1 Replica per Master
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.1.4:7004 to 192.168.1.1:7001
...
[OK] All 16384 slots covered.

3. Verify Cluster Status

# Cluster info
redis-cli -c -h 192.168.1.1 -p 7001 cluster info

# Node list
redis-cli -c -h 192.168.1.1 -p 7001 cluster nodes

# Slot distribution check
redis-cli --cluster check 192.168.1.1:7001

4. Local Test Environment with Docker Compose

# docker-compose.yml
version: '3.8'
services:
  redis-1: { image: redis:7-alpine, command: redis-server /etc/redis.conf, volumes: [./redis.conf:/etc/redis.conf], ports: ["7001:7001"] }
  redis-2: { image: redis:7-alpine, command: redis-server /etc/redis.conf --port 7002, ports: ["7002:7002"] }
  redis-3: { image: redis:7-alpine, command: redis-server /etc/redis.conf --port 7003, ports: ["7003:7003"] }
  redis-4: { image: redis:7-alpine, command: redis-server /etc/redis.conf --port 7004, ports: ["7004:7004"] }
  redis-5: { image: redis:7-alpine, command: redis-server /etc/redis.conf --port 7005, ports: ["7005:7005"] }
  redis-6: { image: redis:7-alpine, command: redis-server /etc/redis.conf --port 7006, ports: ["7006:7006"] }
docker-compose up -d
# Initialize cluster
docker exec redis-1 redis-cli --cluster create \
  redis-1:7001 redis-2:7002 redis-3:7003 \
  redis-4:7004 redis-5:7005 redis-6:7006 \
  --cluster-replicas 1 --cluster-yes

5. Client Connection

Spring Boot (Lettuce)

spring:
  data:
    redis:
      cluster:
        nodes:
          - 192.168.1.1:7001
          - 192.168.1.2:7002
          - 192.168.1.3:7003
        max-redirects: 3
      password: your-password
      lettuce:
        cluster:
          refresh:
            adaptive: true        # Auto-detect topology changes
            period: 30s

Python (redis-py)

from redis.cluster import RedisCluster

rc = RedisCluster(
    startup_nodes=[
        {"host": "192.168.1.1", "port": 7001},
        {"host": "192.168.1.2", "port": 7002},
    ],
    decode_responses=True,
    skip_full_coverage_check=True,
)

rc.set("key", "value")
rc.get("key")

6. Hash Tags — Placing Keys on the Same Slot

Multi-key commands (MGET, MSET, pipelines) only work on same-slot keys.

# Risky: may land on different slots
rc.mget("user:1:profile", "user:1:session")  # CROSSSLOT error possible

# Safe: Hash Tag guarantees same slot
rc.mget("{user:1}:profile", "{user:1}:session")
# CRC16("user:1") % 16384 → same slot

7. Adding Nodes Online (Live Scaling)

# Add a new Master
redis-cli --cluster add-node \
  192.168.1.7:7007 \    # New node
  192.168.1.1:7001       # Any existing cluster node

# Rebalance slots
redis-cli --cluster reshard 192.168.1.1:7001
# Enter number of slots to move → enter new node ID → 'all' (move evenly from all)

# Add a Replica
redis-cli --cluster add-node \
  192.168.1.8:7008 \
  192.168.1.1:7001 \
  --cluster-slave \
  --cluster-master-id <master-node-id>

8. Failover Testing

# Simulate Master failure
redis-cli -h 192.168.1.1 -p 7001 DEBUG SLEEP 30

# In another terminal, watch the Replica get promoted
watch redis-cli --cluster check 192.168.1.1:7001

After cluster-node-timeout 5000 (5 seconds), the Replica is promoted to Master.

Operations Checklist

  • Verify all slots covered: cluster info | grep cluster_state:ok
  • Confirm at least 1 Replica per Master
  • maxmemory and maxmemory-policy configured
  • Client auto-reconnect + topology refresh enabled
  • Hash Tag usage rules shared with the team
  • Regular failover drills (quarterly)