一主二从三哨兵
一、架构组成
“一主二从三哨兵” 架构由 3 类角色组成,共 6 个容器(或实例):
- 1 个主节点(Master):处理读写请求,是核心数据节点。
- 2 个从节点(Slave):通过主从复制同步主节点数据,仅处理读请求(默认),主节点故障时可被哨兵选举为新主节点。
- 3 个哨兵节点(Sentinel):监控主从节点状态,判断主节点是否下线,当主节点故障时自动触发故障转移(Failover),将某个从节点升级为新主节点。
二、核心组件作用
1. 主节点(Master)
- 功能:接收所有写请求(如
SET
、HSET
),并通过主从复制将数据同步到从节点。
- 特点:默认只有主节点可写,从节点只读(通过配置
slave-read-only yes
控制),确保数据一致性。
- Docker 配置关键点:
- 绑定所有网络接口(
bind 0.0.0.0
),允许容器外部访问。
- 配置持久化(RDB/AOF),避免数据丢失。
- 设置访问密码(
requirepass
)和主从同步密码(masterauth
,与从节点一致)。
2. 从节点(Slave)
- 功能:通过
replicaof <master-ip> <master-port>
配置同步主节点数据,仅处理读请求(分担主节点读压力)。
- 特点:主节点故障后,可被哨兵选举为新主节点,升级后自动切换为可写状态。
- Docker 配置关键点:
- 与主节点使用相同的密码配置(
masterauth
需匹配主节点 requirepass
)。
- 关闭保护模式(
protected-mode no
),允许跨容器访问。
- 配置持久化路径(与主节点独立,避免数据冲突)。
3. 哨兵节点(Sentinel)
- 功能:
- 监控:定期检查主从节点是否存活(通过
PING
命令)。
- 判断下线:当主节点不可达时,先标记为 “主观下线(SDOWN)”;若超过
quorum
个哨兵达成共识,则标记为 “客观下线(ODOWN)”。
- 故障转移:客观下线后,选举哨兵 leader 执行故障转移,将最优从节点升级为新主节点,其他从节点切换到新主节点同步数据。
- Docker 配置关键点:
- 配置监控主节点(
sentinel monitor <master-name> <master-ip> <master-port> <quorum>
),quorum
为达成下线共识的最小哨兵数量(3 哨兵建议设为 2)。
- 设置主节点认证密码(
sentinel auth-pass <master-name> <password>
)。
- 配置下线检测超时(
sentinel down-after-milliseconds
,建议 1000-3000ms)和故障转移超时(sentinel failover-timeout
)。
主从配置
docker-compose.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| version: '3' services: redis1: image: redis container_name: redis1 hostname: redis1 ports: - 6379:6379 - 16379:16379 networks: - redis_net volumes: - ./redis1/conf:/etc/conf - ./redis1/data:/data command: redis-server /etc/conf/redis.conf redis2: image: redis container_name: redis2 hostname: redis2 ports: - 6380:6380 - 16380:16380 networks: - redis_net volumes: - ./redis2/conf:/etc/conf - ./redis2/data:/data command: redis-server /etc/conf/redis.conf
redis3: image: redis container_name: redis3 hostname: redis3 ports: - 6381:6381 - 16381:16381 networks: - redis_net volumes: - ./redis3/conf:/etc/conf - ./redis3/data:/data command: redis-server /etc/conf/redis.conf
networks: redis_net: name: redis_net driver: bridge
|
1 2 3 4 5
| cd redis_service/ docker compose up
|
在 /redis_service/redis1/conf/
下新建主机配置文件 redis.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| databases 10 bind 0.0.0.0
port 6379
requirepass 123456 masterauth 123456
dir /data
dbfilename dump.rdb
rdbcompression yes
stop-writes-on-bgsave-error yes
protected-mode no
repl-diskless-load on-empty-db
save 900 1
save 300 10 save 60 10000
logfile redis.log
|
在 /redis_service/redis2/conf/
下新建从机配置文件 redis.conf
配置后也在/redis_service/redis3/conf/
复制一份,并修改为对应监听端口:6381
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| databases 10 bind 0.0.0.0
port 6380
requirepass 123456 masterauth 123456
dir /data
dbfilename dump.rdb
rdbcompression yes stop-writes-on-bgsave-error yes protected-mode no repl-diskless-load on-empty-db
save 900 1 save 300 10 save 60 10000
logfile redis.log replicaof redis1 6379
|
验证测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| docker compose up -d
docker container ls cd redis_service docker compose ps docker compose stats
docker exec -it redis1 bash redis-cli auth 123456 info
docker exec -it redis2 redis-cli -p 6380 auth 123456 info
set class_name zhiyun70
get class_name
|
哨兵配置
修改docker-compose.yaml
配置文件(添加sentinel1、sentinel2、sentinel3)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| version: '3' services: redis1: image: redis container_name: redis1 hostname: redis1 ports: - 6379:6379 - 16379:16379 networks: - redis_net volumes: - ./redis1/conf:/etc/conf - ./redis1/data:/data command: redis-server /etc/conf/redis.conf redis2: image: redis container_name: redis2 hostname: redis2 ports: - 6380:6380 - 16380:16380 networks: - redis_net volumes: - ./redis2/conf:/etc/conf - ./redis2/data:/data command: redis-server /etc/conf/redis.conf
redis3: image: redis container_name: redis3 hostname: redis3 ports: - 6381:6381 - 16381:16381 networks: - redis_net volumes: - ./redis3/conf:/etc/conf - ./redis3/data:/data command: redis-server /etc/conf/redis.conf
sentinel1: image: redis container_name: sentinel1 hostname: sentinel1 ports: - 26379:26379 networks: - redis_net volumes: - ./sentinel1/conf:/etc/conf - ./sentinel1/data:/data command: redis-sentinel /etc/conf/sentinel.conf
sentinel2: image: redis container_name: sentinel2 hostname: sentinel2 ports: - 26380:26379 networks: - redis_net volumes: - ./sentinel2/conf:/etc/conf - ./sentinel2/data:/data command: redis-sentinel /etc/conf/sentinel.conf
sentinel3: image: redis container_name: sentinel3 hostname: sentinel3 ports: - 26381:26379 networks: - redis_net volumes: - ./sentinel3/conf:/etc/conf - ./sentinel3/data:/data command: redis-sentinel /etc/conf/sentinel.conf
networks: redis_net: name: redis_net driver: bridge
|
1 2 3
| docker compose down docker compose up -d
|
刷新目录后会生成三个文件夹(sentinel1、sentinel2、sentinel3)
在 /redis_service/sentinel1/conf/
下新建哨兵配置文件 sentinel.conf
配置后分别复制一份到sentinel2、sentinel3的conf下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
bind 0.0.0.0
port 26379
pidfile "/data/redis-sentinel.pid"
dir "/tmp"
requirepass 123456
daemonize no
protected-mode no
logfile "/data/redis-sentinel.log"
sentinel resolve-hostnames yes
sentinel monitor redisMaster redis1 6379 2
sentinel auth-pass redisMaster 123456
sentinel down-after-milliseconds redisMaster 100
sentinel parallel-syncs redisMaster 1
sentinel failover-timeout redisMaster 600
|
启动服务时需要关闭sentinel.conf
的编辑窗口,因为运行时需要往上面写入日志,打开窗口会占用其写入进程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| chmod a+w /root/redis_service/sentinel1/conf/sentinel.conf chmod a+w /root/redis_service/sentinel2/conf/sentinel.conf chmod a+w /root/redis_service/sentinel3/conf/sentinel.conf
chmod a+w /root/redis_service/sentinel1/data chmod a+w /root/redis_service/sentinel2/data chmod a+w /root/redis_service/sentinel3/data
cd /root/redis_service/ docker compose down docker compose up -d docker container ls
docker exec -it redis2 redis-cli -p 6380 auth 123456 info
docker exec -it sentinel3 redis-cli -p 26379 auth 123456 info
|
验证测试
1 2 3 4 5 6 7 8 9 10 11 12 13
| cd /root/redis_service
docker container stop redis1
info sentinel
docker exec -it sentinel1 redis-cli -p 26379 -a 123456 info sentinel
docker exec -it redis2 redis-cli -p 6380 -a 123456 info
|