Redis搭建哨兵模式架构
使用Docker安装
因为配置太复杂,所以这里我们使用 docker compose 来一键部署
不使用内部网络搭建
编写redis主从docker-compose.yml
version: '3'
services:
master:
image: redis
container_name: redis-master
restart: always
command: redis-server --requirepass test123 --appendonly yes
ports:
- 6390:6379
volumes:
- /root/test_redis/master_slave/data1:/data
slave1:
image: redis
container_name: redis-slave1
restart: always
command: redis-server --slaveof ${your_ip} 6390 --requirepass test123 --masterauth test123 --appendonly yes
ports:
- 6391:6379
volumes:
- /root/test_redis/master_slave/data2:/data
slave2:
image: redis
container_name: redis-slave2
restart: always
command: redis-server --slaveof ${your_ip} 6390 --requirepass test123 --masterauth test123 --appendonly yes
ports:
- 6392:6379
volumes:
- /root/test_redis/master_slave/data3:/data
配置主机密码为 test123 并开启AOF,端口号为6390
启动Redis主从
docker-compose up -d
编写哨兵docker-compose.yml
version: '3'
services:
sentinel1:
image: redis
container_name: redis-sentinel1
restart: always
ports:
- 26379:26379
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- /root/test_redis/sentinel/sentinel1.conf:/usr/local/etc/redis/sentinel.conf
sentinel2:
image: redis
container_name: redis-sentinel2
restart: always
ports:
- 26380:26379
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- /root/test_redis/sentinel/sentinel2.conf:/usr/local/etc/redis/sentinel.conf
sentinel3:
image: redis
container_name: redis-sentinel3
ports:
- 26381:26379
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- /root/test_redis/sentinel/sentinel3.conf:/usr/local/etc/redis/sentinel.conf
注意,两个docker-compose.yml文件必须位于不同的目录下,也要打开防火墙的端口 26379,26380,26381。
编写哨兵sentinel.conf
# 自定义集群名,其中 master_host 为 redis-master 的 ip,6379 为 redis-master 的端口,2 为最小投票数(因为有 3 台 Sentinel 所以可以设置成 2)
port 26379
dir /tmp
sentinel monitor mymaster ${master_host} 6390 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel auth-pass mymaster test123
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
将上述文件拷贝3份分别命名为sentinel1.conf、sentinel2.conf、sentinel3.conf,与docker-compose.yml中的配置文件对应。
启动哨兵
docker-compose up -d
查看容器,可以看到哨兵和主从redis都起来了
关掉master节点
docker stop redis-master
出现的问题
master节点停掉之后,哨兵并没有将另外的slave节点提升为master,结合网上资料,可能是因为没有使用同一个网络,所以哨兵和master/slave节点不能进行通信。
使用内部网络搭建
配置docker-compose.yml文件
version: "3"
networks:
redis-replication:
driver: bridge
ipam:
config:
- subnet: 172.25.0.0/24
services:
master:
image: redis
container_name: redis-master
ports:
- "6380:6379"
volumes:
- "/root/test_redis/sentinel_with_network/redis1.conf:/etc/redis.conf"
- "/root/test_redis/sentinel_with_network/data1:/data"
command: ["redis-server", "/etc/redis.conf"]
restart: always
networks:
redis-replication:
ipv4_address: 172.25.0.101
slave1:
image: redis
container_name: redis-slave1
ports:
- "6381:6379"
volumes:
- "/root/test_redis/sentinel_with_network/redis2.conf:/etc/redis.conf"
- "/root/test_redis/sentinel_with_network/data2:/data"
command: ["redis-server", "/etc/redis.conf"]
restart: always
networks:
redis-replication:
ipv4_address: 172.25.0.102
slave2:
image: redis
container_name: redis-slave2
ports:
- "6382:6379"
volumes:
- "/root/test_redis/sentinel_with_network/redis3.conf:/etc/redis.conf"
- "/root/test_redis/sentinel_with_network/data3:/data"
command: ["redis-server", "/etc/redis.conf"]
restart: always
networks:
redis-replication:
ipv4_address: 172.25.0.103
sentinel1:
image: redis
container_name: redis-sentinel1
ports:
- "26380:26379"
volumes:
- "/root/test_redis/sentinel_with_network/sentinel1.conf:/etc/sentinel.conf"
command: ["/bin/bash", "-c", "cp /etc/sentinel.conf /sentinel.conf && redis-sentinel /sentinel.conf"]
restart: always
networks:
redis-replication:
ipv4_address: 172.25.0.201
sentinel2:
image: redis
container_name: redis-sentinel2
ports:
- "26381:26379"
volumes:
- "/root/test_redis/sentinel_with_network/sentinel2.conf:/etc/sentinel.conf"
command: ["/bin/bash", "-c", "cp /etc/sentinel.conf /sentinel.conf && redis-sentinel /sentinel.conf"]
restart: always
networks:
redis-replication:
ipv4_address: 172.25.0.202
sentinel3:
image: redis
container_name: redis-sentinel3
ports:
- "26382:26379"
volumes:
- "/root/test_redis/sentinel_with_network/sentinel3.conf:/etc/sentinel.conf"
command: ["/bin/bash", "-c", "cp /etc/sentinel.conf /sentinel.conf && redis-sentinel /sentinel.conf"]
restart: always
networks:
redis-replication:
ipv4_address: 172.25.0.203
配置 redis.conf 文件
- Master:
port 6379
pidfile /var/run/redis_6379.pid
protected-mode no
timeout 0
tcp-keepalive 300
loglevel notice
requirepass szz123
masterauth szz123
################################# REPLICATION #################################
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
##################################### RDB #####################################
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dir ./
##################################### AOF #####################################
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
aof-load-truncated yes
aof-use-rdb-preamble no
由于在切换master的时候,原本的master可能变成slave,故也需要在原本的master上配置masterauth
- Slave1:
在 REPLICATION 中添加 slaveof 设置即可:
slaveof 172.25.0.101 6379
- Slave2:
slaveof 172.25.0.101 6379
redis1.conf,redis2.conf,redis3.conf
配置 sentinel.conf 文件
三个哨兵文件夹都配置一份
# 所有哨兵端口都一致,因为使用 Docker 桥接网络映射
port 26379
# 哨兵设置,所有哨兵皆一致,都指向 Master
sentinel monitor mymaster 172.25.0.101 6379 2
sentinel auth-pass mymaster test123
sentinel parallel-syncs mymaster 1
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000
bind 0.0.0.0
protected-mode no
daemonize no
pidfile /var/run/redis-sentinel.pid
logfile ""
dir /tmp
sentinel1.conf,sentinel2.conf,sentinel3.conf 内容都一样
启动服务
docker-compose up -d
查看主从配置是否正常
Master 的输出:
查看各哨兵是否正常
Sentinel1:
可以看到 +monitor 配置、两次 +sentinel 记录和两次 +slave 记录,且各连接的 ip 和 port 信息都正确,此哨兵正常运行。Sentinel2 和 Sentinel3 也是同样的输出。
验证哨兵
Master宕机
主动停止 Master 容器,等待配置的失活判定时间过后,看哨兵是否识别并选举新的 Master:
docker stop redis-master
此时 Sentinel1 输出
- 哨兵 sdown 主观判断 Master 失活,接着所有哨兵 odown 客观判断 Master 失活。此时 +new-epoch 1 进入第一轮选举。
- 接着 +selected-slave slave 172.25.0.102:6379 选举出 102,即 Slave2 作为新的 Master,再 +promoted-slave 推举 Slave2 为新的 Master。
- 最终依旧会去看 101 是否回来了,+sdown slave 172.25.0.101:6379 172.25.0.101 6379 @ mymaster 172.25.0.102 6379 发现 101 还没上线。
登录 slave2 查看
info replication
结果可以看到确实已经变成了master,且有一个slave
原 Master 重新上线
查看哨兵反应:
发现 -sdown slave 172.25.0.101:6379,即把 101 Slave(原 Master)的 down 状态取消掉。
再次查看 slave2
info replication
已经有了两个slave,至此,关于哨兵模式的配置终于搞定了。
参考
【Redis】docker compose 部署哨兵集群模式-重要
5分钟实现用docker搭建Redis集群模式和哨兵模式
使用Docker-Compose搭建高可用redis哨兵集群-主要是桥接网络
Docker Compose-菜鸟教程