Redis High Availability: Sentinel and Cluster
Sentinel handles master failure through automatic failover, while Cluster shards data across 16,384 hash slots to scale availability and capacity together.
Contents
Sentinel detects master failure and switches over to a replica automatically, while Cluster splits data into 16,384 slots spread across several masters.
Availability and scaling are separate axes
A standalone instance handles all reads and writes with a single Redis process. The structure is simple enough for development and prototypes, but if that node dies, all of the data goes with it. In production, eliminating this single point of failure comes first.
The problem then splits in two. One half is availability, taking over without interruption when the master dies. The other is horizontal scaling, holding more data than fits in one node's memory. Sentinel addresses the first; Cluster addresses both.
Making Cluster the default because it solves both at once only inflates operational complexity. The two modes solve different axes, so the choice should follow from data size and how often multi-key operations are used.
Sentinel monitoring and automatic failover
Sentinel is a high-availability configuration that layers monitoring and automatic failover on top of master-replica replication. Separate Sentinel processes watch the master and its replicas, and when the master stops responding, one replica is promoted to become the new master. The recommended minimum deployment is one master, two replicas, and three Sentinels, for six processes total.
Three Sentinels exist because the down decision requires a quorum. A single Sentinel losing sight of the master may just be a transient network problem, so agreement among several Sentinels reduces false calls. Declaring the master down and promoting a replica proceeds in this order.
1. Three Sentinels monitor the master
2. Two Sentinels judge the master to be down
3. Quorum of 2 satisfied -> failover approved
4. Replica 1 is promoted to the new master
5. Replica 2 resumes replication from the new master
6. Clients are redirected to the new master automaticallyDetection sensitivity and speed come down to a few lines in sentinel.conf. Here is an example configuration.
port 5000
sentinel monitor mymaster 10.0.0.10 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1| Setting | Example value | Meaning |
|---|---|---|
sentinel monitor mymaster <ip> <port> 2 | quorum 2 | Minimum number of Sentinels that must agree the master is down |
down-after-milliseconds | 5000 | How long (in milliseconds) silence counts as being down |
failover-timeout | 60000 | How long to wait before retrying a failover |
parallel-syncs | 1 | How many replicas resynchronize with the new master at once |
These values set how sensitive failure handling is. A short down-after fails over quickly but can mistake a transient delay for an outage. A larger parallel-syncs speeds recovery but concentrates all the resynchronization load at once.
Clients do not hardcode the master address; they ask Sentinel for it. In redis-py, the Sentinel object locates the current master, and the library reconnects even when the address changes through a failover.
from redis.sentinel import Sentinel
sentinel = Sentinel([('sentinel1', 5000), ('sentinel2', 5000)])
master = sentinel.master_for('mymaster', socket_timeout=0.1)
master.set('key', 'value')Sentinel's limit is that there is still only one master. Write throughput and data capacity stay bound to a single node, so you gain availability but not horizontal scaling. That makes it a fit for small and mid-sized deployments where the data fits in one node's memory (under 100GB, per my notes).
Cluster hash slot sharding
Cluster divides data into 16,384 hash slots spread across several masters. Which slot a key lands in is determined by CRC16(key) % 16384, and the masters split the slot ranges among themselves. The recommended minimum deployment is three masters and three replicas for six nodes, scaling up to roughly 1,000 nodes per my notes.
Each master owns only its own slot range, so writes spread across three nodes. A replica is a copy of the master it is paired with and is promoted automatically when that master dies. Cluster has this failover built in, so no separate Sentinel is needed.
By default the whole key is hashed, so related keys scatter into different slots. To pin them to the same slot, specify a hash tag with curly braces.
# only {user:1001} inside the braces is hashed -> same slot -> same node
redis.mget("{user:1001}:profile", "{user:1001}:orders")Multi-key commands spanning different slots are rejected. Keys scattered across different nodes cannot be handled atomically in one operation.
# rejected when the slots differ
redis.mget("user:1001", "user:1002")
# CROSSSLOT Keys in request don't hash to the same slotWhen grouping with hash tags, watch out for hotspots. Identical tags such as {pending}:1 and {pending}:2 pile every key onto one node. A high-cardinality tag such as {user_id}:pending:1 spreads them across nodes.
Cluster mode is enabled in the configuration, and the create command distributes slots automatically. Below are the redis.conf and creation example from my notes.
port 6379
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-require-full-coverage yesredis-cli --cluster create \
10.0.0.1:6379 10.0.0.1:6380 \
10.0.0.2:6379 10.0.0.2:6380 \
10.0.0.3:6379 10.0.0.3:6380 \
--cluster-replicas 1--cluster-replicas 1 means attaching one replica to each master. cluster-node-timeout is how long before a node is considered dead, set to 15,000 milliseconds in this example.
MOVED and ASK redirections
When a client sends a key to the wrong node, Cluster returns a redirection response instead of an error. There are two kinds, and they signal different situations.
MOVED signals a permanent move: the slot has a new owner. It appears when the client's cached slot-to-node mapping is stale, and the client reissues the request to the node named in the response and refreshes its own mapping.
ASK is a temporary redirection that appears only during resharding. When a slot is mid-migration and a particular key has already moved to the target node, ASK tells the client to send that one key to the target. The slot mapping itself is not updated.
Resharding moves slots without downtime, serving requests with ASK in the meantime.
Step 1: the source node marks the slot as MIGRATING
Step 2: the target node marks it as IMPORTING
Step 3: the MIGRATE command moves keys one at a time, atomically
Step 4: requests arriving mid-move are served with ASK redirectionsOnce resharding finishes, the slot's new owner is settled and subsequent requests are handled with MOVED. A cluster-aware client processes both responses automatically, so application code never deals with slot locations.
from redis.cluster import RedisCluster
rc = RedisCluster.from_url("redis://10.0.0.1:6379")
rc.set("key", "value") # the library handles the slot-to-node mappingChoosing a mode, and consistency
The trade-offs between the two modes fit into a table. Below is the deployment mode selection matrix.
| Item | Standalone | Sentinel | Cluster |
|---|---|---|---|
| High availability | None | Automatic failover | Per-shard failover |
| Horizontal scaling | Not possible | Not possible (vertical only) | Up to ~1,000 nodes |
| Data capacity | Single node | Single master | Sum across masters |
| Minimum nodes | 1 | 5+ | 6 |
| Multi-key operations | Fully supported | Fully supported | Same slot only |
| Operational complexity | Low | Medium | High |
| Consistency | Strong | Asynchronous | Asynchronous |
Compressed to one line, the criteria are data size and multi-key frequency. Under 100GB with heavy multi-key use, Sentinel is the fit. Beyond that, with a need for more write throughput, Cluster is the choice.
Consistency is the weak point in both modes. Replication is asynchronous, so if the master dies after replying to the client but before the write propagates to a replica, that write can be lost. The loss window is at most a few seconds, per my notes.
Configuration reduces the chance of loss. The WAIT command blocks until a given number of replicas have received the write, and the min-replicas settings reject writes when too few replicas are available. Turning on the append-only file (AOF) also reduces node-level loss.
# wait up to 1 second for 2 replicas to receive the write
redis.execute_command("WAIT", 2, 1000)min-replicas-to-write 1
min-replicas-max-lag 10
appendonly yes
appendfsync everysecThese mechanisms trade latency for availability. WAIT and min-replicas raise safety, but a slow replica blocks writes. For data such as a cache, where a small amount of loss is acceptable, there is no need to turn them on.
Summary
Sentinel and Cluster are grouped together as high-availability tooling, but they solve different problems. Sentinel adds monitoring and automatic failover on top of master-replica replication, solving availability only and leaving a single master. Cluster shards data into 16,384 slots to scale availability and capacity together, at the cost of multi-key restrictions and operational complexity.
Start the decision from data size and multi-key operation frequency. Under 100GB with heavy multi-key use, Sentinel works; beyond that, with a need for write scaling, Cluster is the safer pick. Replication is asynchronous in both modes, so reducing loss means enabling WAIT, min-replicas, and AOF according to what the data can tolerate.