docker-compose配置redis哨兵详细步骤和配置文件
目录结构调整
redis-cluster/
├── config/
│ ├── master.conf # 主节点配置
│ ├── slave1.conf # 从节点1配置
│ ├── slave2.conf # 从节点2配置
│ ├── sentinel1.conf # 哨兵1配置
│ ├── sentinel2.conf # 哨兵2配置
│ └── sentinel3.conf # 哨兵3配置
└── docker-compose.yml # 包含哨兵的docker-compose配置
Redis配置文件更新
1. config/master.conf
(主节点)
port 6379
bind 0.0.0.0
protected-mode no
logfile "redis-master.log"
dir /data
save 900 1
save 300 10
save 60 10000
requirepass yourpassword
masterauth yourpassword
2. config/slave1.conf
(从节点1)
port 6380
bind 0.0.0.0
protected-mode no
logfile "redis-slave1.log"
dir /data
slaveof redis-master 6379
requirepass yourpassword
masterauth yourpassword
3. config/slave2.conf
(从节点2)
port 6381
bind 0.0.0.0
protected-mode no
logfile "redis-slave2.log"
dir /data
slaveof redis-master 6379
requirepass yourpassword
masterauth yourpassword
哨兵配置文件
4. config/sentinel1.conf
(哨兵1)
port 26379
bind 0.0.0.0
protected-mode no
logfile "sentinel1.log"
dir /data# 监控主节点,mymaster是集群名称,2是触发故障转移所需的最小同意票数
sentinel monitor mymaster redis-master 6379 2# 主节点不可用的判定时间(毫秒)
sentinel down-after-milliseconds mymaster 5000# 故障转移超时时间(毫秒)
sentinel failover-timeout mymaster 10000# 认证密码
sentinel auth-pass mymaster yourpassword
5. config/sentinel2.conf
(哨兵2)
port 26379
bind 0.0.0.0
protected-mode no
logfile "sentinel2.log"
dir /data
sentinel monitor mymaster redis-master 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel auth-pass mymaster yourpassword
6. config/sentinel3.conf
(哨兵3)
port 26379
bind 0.0.0.0
protected-mode no
logfile "sentinel3.log"
dir /data
sentinel monitor mymaster redis-master 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel auth-pass mymaster yourpassword
更新后的docker-compose.yml
version: '3.8'services:# Redis主节点redis-master:image: redis:7.0container_name: redis-masterports:- "6379:6379"volumes:- ./config/master.conf:/usr/local/etc/redis/redis.conf- redis-data-master:/datacommand: ["redis-server", "/usr/local/etc/redis/redis.conf"]healthcheck:test: ["CMD", "redis-cli", "-a", "yourpassword", "ping"]interval: 5stimeout: 5sretries: 5networks:- redis-network# Redis从节点1redis-slave1:image: redis:7.0container_name: redis-slave1ports:- "6380:6380"volumes:- ./config/slave1.conf:/usr/local/etc/redis/redis.conf- redis-data-slave1:/datacommand: ["redis-server", "/usr/local/etc/redis/redis.conf"]healthcheck:test: ["CMD", "redis-cli", "-a", "yourpassword", "-p", "6380", "ping"]interval: 5stimeout: 5sretries: 5depends_on:- redis-masternetworks:- redis-network# Redis从节点2redis-slave2:image: redis:7.0container_name: redis-slave2ports:- "6381:6381"volumes:- ./config/slave2.conf:/usr/local/etc/redis/redis.conf- redis-data-slave2:/datacommand: ["redis-server", "/usr/local/etc/redis/redis.conf"]healthcheck:test: ["CMD", "redis-cli", "-a", "yourpassword", "-p", "6381", "ping"]interval: 5stimeout: 5sretries: 5depends_on:- redis-masternetworks:- redis-network# 哨兵节点1redis-sentinel1:image: redis:7.0container_name: redis-sentinel1ports:- "26379:26379"volumes:- ./config/sentinel1.conf:/usr/local/etc/redis/sentinel.conf- sentinel-data1:/datacommand: ["redis-sentinel", "/usr/local/etc/redis/sentinel.conf"]healthcheck:test: ["CMD", "redis-cli", "-p", "26379", "ping"]interval: 5stimeout: 5sretries: 5depends_on:- redis-master- redis-slave1- redis-slave2networks:- redis-network# 哨兵节点2redis-sentinel2:image: redis:7.0container_name: redis-sentinel2ports:- "26380:26379"volumes:- ./config/sentinel2.conf:/usr/local/etc/redis/sentinel.conf- sentinel-data2:/datacommand: ["redis-sentinel", "/usr/local/etc/redis/sentinel.conf"]healthcheck:test: ["CMD", "redis-cli", "-p", "26380", "ping"]interval: 5stimeout: 5sretries: 5depends_on:- redis-master- redis-slave1- redis-slave2networks:- redis-network# 哨兵节点3redis-sentinel3:image: redis:7.0container_name: redis-sentinel3ports:- "26381:26379"volumes:- ./config/sentinel3.conf:/usr/local/etc/redis/sentinel.conf- sentinel-data3:/datacommand: ["redis-sentinel", "/usr/local/etc/redis/sentinel.conf"]healthcheck:test: ["CMD", "redis-cli", "-p", "26381", "ping"]interval: 5stimeout: 5sretries: 5depends_on:- redis-master- redis-slave1- redis-slave2networks:- redis-networkvolumes:redis-data-master:redis-data-slave1:redis-data-slave2:sentinel-data1:sentinel-data2:sentinel-data3:networks:redis-network:driver: bridge
部署和验证步骤
- 创建目录和配置文件,确保权限正确:
mkdir -p config
chmod -R 644 config/
- 启动集群:
docker-compose up -d
- 验证Redis主从状态:
# 查看主节点信息
docker exec -it redis-master redis-cli -a yourpassword info replication# 查看从节点信息
docker exec -it redis-slave1 redis-cli -a yourpassword -p 6380 info replication
docker exec -it redis-slave2 redis-cli -a yourpassword -p 6381 info replication
- 验证哨兵状态:
# 从任一哨兵获取集群信息
docker exec -it redis-sentinel1 redis-cli -p 26379
127.0.0.1:26379> SENTINEL masters
127.0.0.1:26379> SENTINEL slaves mymaster
测试故障转移
- 模拟主节点故障:
docker stop redis-master
-
等待约10秒(根据sentinel配置的超时时间),哨兵会自动将一个从节点提升为主节点
-
验证新的主节点:
# 查看哨兵状态
docker exec -it redis-sentinel1 redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster# 确认客户端可以连接到新主节点
redis-cli -h <new-master-ip> -p 6379 -a yourpassword ping
- 恢复原主节点:
docker start redis-master
原主节点将作为从节点重新加入集群
客户端连接配置
应用程序应通过哨兵获取当前主节点地址,而不是直接连接固定节点。例如,使用Redis客户端连接时:
# Python示例
from redis.sentinel import Sentinelsentinel = Sentinel([('localhost', 26379),('localhost', 26380),('localhost', 26381)
], socket_timeout=0.5)# 获取主节点连接
master = sentinel.master_for('mymaster', socket_timeout=0.5, password='yourpassword')# 获取从节点连接(用于读操作)
slave = sentinel.slave_for('mymaster', socket_timeout=0.5, password='yourpassword')# 执行命令
master.set('foo', 'bar')
value = slave.get('foo')
print(value) # 输出: b'bar'
这个配置方案实现了一个完整的Redis高可用集群,包含一主二从和三个哨兵节点,可以自动进行故障转移和恢复。