Redis 哨兵
Redis的主从复制模式下,一旦这个主节点不能提供服务,就需要人工进行主从切换,这是非常麻烦的。
主从复制局限性
主从复制能够很好的平衡保证数据一致性的问题,但是当遇到故障的时候就会遗留一些问题
- 主节点发生故障时,需要手动切换主节点,是非常复杂
- 主节点能够将"读"压力分担到从节点中,但是主节点还是承担了"写"的压力,受到了单机的限制
来看第一个问题,如果出现故障了,大致的流程是:
- 检查主节点是否健康,还是否能工作 / 抢救
- 如果短时间不能排查问题,则需要手动挑一个从节点设置为新的主节点
- 把选好的从节点通过
slaveof no one升级成主节点 - 再将原来的从节点通过
slaveof 主节点的ip port,连上新的主节点 - 然后再修改客户端的配置,让客户端能够顺利的连接到另一个主节点
这步骤看着都头疼🤕...于是Redis就引入了哨兵来解决这个问题。通常哨兵也不会只设置一个,会部署一个哨兵集群,防止哨兵挂了 / 单个容易误判的情况
实现原理

正常运行状态时,哨兵集群每个都是单独的 redis-sentinel 进程,会监控现有的 redis-master 和 slave,他们的监控时通过 TCP 这样的长链接定期发送心跳包
不过一个哨兵节点发现主节点挂了还不够,需要多个哨兵节点来共同认同这件事才会进行接下来的操作,主要是为了防止误判
当多数都认为主节点挂了,就会接着往下操作
- 哨兵节点中会先挑选出一个 leader,由这个 leader 来负责从现有的从节点中挑选一个作为新的主节点(会通过投票🗳️的方式进行挑选 leader,每个哨兵都会有一票,多票数的就当 leader)
- 挑选出从节点后,哨兵会控制这个节点执行
slaveof no one的操作,并控制其他节点,修改slave of到新的主节点上 - 然后自动会通知客户端
Docker 部署
我们使用 docker 来进行多个 redis 的部署练习,这里我们按照上图的一样的结构:一个主节点,两个从节点,一个哨兵集群(三个 sentinel)
主从节点配置
我们在云服务器上运行 docker,首先要安装 docker: apt install docker-compose
如果本身有 redis 进程,我们可以先停掉之前的服务:service redis-server stop
然后使用 Docker 拉取 redis 镜像:docker pull redis:5.0.9
,首次拉取的话可能会出现拉取超时的情况,这是由于国内风控的原因,要么让你的云服务器加上代理,要么就配置镜像源,我这里就配置了镜像源,只需要逐条执行即可
bash
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json >/dev/null <<'EOF'
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://hub-mirror.c.163.com"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo docker pull redis:5.0.9
最后使用
docker images 查看镜像是否拉取成功
我们需要创建两个文件夹,建议在主目录中建一个 redis 文件夹,在里面再分成 redis-data 和 redis-sentinel 文件夹,命令为
bash
mkdir redis
mkdir redis-data
mkdir redis-sentinel
最终你在 redis 目录中会有这两个文件夹

进入到 redis-data 中:cd redis-data,新建配置文件: vim docker-compose.yml,注意这个文件名称必须是这个
然后把这段配置粘贴进去
txt
version: '3.7'
services:
master:
image: 'redis:5.0.9'
container_name: redis-master
restart: always
command: redis-server --appendonly yes
ports:
- 6379:6379
slave1:
image: 'redis:5.0.9'
container_name: redis-slave1
restart: always
command: redis-server --appendonly yes --slaveof redis-master 6379
ports:
- 6380:6379
slave2:
image: 'redis:5.0.9'
container_name: redis-slave2
restart: always
command: redis-server --appendonly yes --slaveof redis-master 6379
ports:
- 6381:6379
最后启动:docker-compose up -d
哨兵配置
进入到哨兵文件夹:cd redis-sentinel,同样的要创建配置文件
txt
version: '3.7'
services:
sentinel1:
image: 'redis:5.0.9'
container_name: redis-sentinel-1
restart: always
command: redis-sentinel /etc/redis/sentinel.conf
volumes:
- ./sentinel1.conf:/etc/redis/sentinel.conf
ports:
- 26379:26379
sentinel2:
image: 'redis:5.0.9'
container_name: redis-sentinel-2
restart: always
command: redis-sentinel /etc/redis/sentinel.conf
volumes:
- ./sentinel2.conf:/etc/redis/sentinel.conf
ports:
- 26380:26379
sentinel3:
image: 'redis:5.0.9'
container_name: redis-sentinel-3
restart: always
command: redis-sentinel /etc/redis/sentinel.conf
volumes:
- ./sentinel3.conf:/etc/redis/sentinel.conf
ports:
- 26381:26379
# 这是解析处于不同的局域网的主节点,主从节点上从另一个docker-compose配置的,这个docker内无法解析此域名
# 用命令 docker network ls 能列出 docker 中的局域网
networks:
default:
external:
name: redis-data_default
最后执行 docker-compose up -d -d 的意思是在后台运行,执行到这里就部署完成了🎉
如果想查看 redis 的日志的话可以使用 docker-compose logs 查看,具体如图
这是各个哨兵节点的日志

还能看主从节点的,只需调到对应的文件夹即可