Redis Sentinel Architecture Overview
Redis Sentinel provides a robust high-availability solution for Redis instances. Unlike Redis Cluster, which handles data sharding across multiple masters, Sentinel focuses on monitoring, notification, and automatic failover for a single master-slave topology. The system monitors master and slave instances, notifies administrators of state changes, and automatically promotes a slave to master if the primary instance fails, reconfiguring other slaves to follow the new leader.
Building the Container Image
To create a versatile deployment, the Docker image is designed to handle three distinct roles: Master, Slave, and Sentinel. This is achieved using a parameterized entrypoint script that modifies configuration files at runtime based on environment variables.
Configuration Templates
First, define the Redis configuration template (redis.tmpl). This file uses placeholders for the port and omits the replication directive by default.
# redis.tmpl
port {{REDIS_PORT}}
appendonly yes
slave-read-only yes
Next, define the Sentinel configuration template (sentinel.tmpl). This monitors the master group and defines the quorum required for failover.
# sentinel.tmpl
port {{SENTINEL_PORT}}
dir "/tmp"
sentinel monitor mymaster {{MASTER_HOST}} {{MASTER_PORT}} 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
Entrypoint Script Logic
The startup script determines the instance role based on the SERVER_ROLE environment variable. For slave nodes, it appends the replicaof directive to the configuration. For sentinels, it replaces placeholders with the master's connection details.
#!/bin/sh
# launch.sh
ROLE=${SERVER_ROLE:-master}
REDIS_PORT=${REDIS_PORT:-6379}
MASTER_PORT=${MASTER_PORT:-6379}
SENTINEL_PORT=${SENTINEL_PORT:-26379}
MASTER_HOST=${MASTER_HOST:-redis-master}
CONFIG_FILE="/etc/redis/redis.conf"
SENTINEL_FILE="/etc/redis/sentinel.conf"
case "$ROLE" in
master)
echo "Starting Redis Master..."
sed -i "s/{{REDIS_PORT}}/$REDIS_PORT/g" $CONFIG_FILE
exec redis-server $CONFIG_FILE
;;
slave)
echo "Starting Redis Slave..."
sed -i "s/{{REDIS_PORT}}/$REDIS_PORT/g" $CONFIG_FILE
echo "replicaof $MASTER_HOST $MASTER_PORT" >> $CONFIG_FILE
exec redis-server $CONFIG_FILE
;;
sentinel)
echo "Starting Redis Sentinel..."
sed -i "s/{{SENTINEL_PORT}}/$SENTINEL_PORT/g" $SENTINEL_FILE
sed -i "s/{{MASTER_HOST}}/$MASTER_HOST/g" $SENTINEL_FILE
sed -i "s/{{MASTER_PORT}}/$MASTER_PORT/g" $SENTINEL_FILE
exec redis-sentinel $SENTINEL_FILE
;;
*)
echo "Unknown role: $ROLE"
exit 1
;;
esac
Dockerfile Definition
The Dockerfile uses the lightweight Alpine version of Redis. It copies the configuration templates and the launch script, ensuring the script has execution permissions.
FROM redis:6-alpine
COPY redis.tmpl /etc/redis/redis.conf
COPY sentinel.tmpl /etc/redis/sentinel.conf
COPY launch.sh /usr/local/bin/launch.sh
RUN chmod +x /usr/local/bin/launch.sh
ENTRYPOINT ["/usr/local/bin/launch.sh"]
Orchestrating the Cluster
The following docker-compose.yml defines a cluster with one master, two slaves, and three sentinel nodes. The network is set to host mode to allow direct communication, and the master is exposed via a fixed hostname.
version: '3.8'
services:
redis-master:
image: custom-redis-ha:latest
container_name: redis-master
environment:
- SERVER_ROLE=master
- REDIS_PORT=6379
network_mode: host
redis-slave:
image: custom-redis-ha:latest
depends_on:
- redis-master
environment:
- SERVER_ROLE=slave
- REDIS_PORT=6380
- MASTER_PORT=6379
- MASTER_HOST=127.0.0.1
network_mode: host
redis-sentinel:
image: custom-redis-ha:latest
depends_on:
- redis-master
environment:
- SERVER_ROLE=sentinel
- SENTINEL_PORT=26379
- MASTER_PORT=6379
- MASTER_HOST=127.0.0.1
network_mode: host
deploy:
replicas: 3