`前言`
Redis中的主从复制模式实现了读写分离,以及断线重连之后的数据一致性,但是并没有解决主机宕机时候出现的故障问题,Redis中使用哨兵模式来解决主机宕机问题。
## 哨兵模式
哨兵(sentinel)是一种运行在特殊模式下的Redis服务器,是Redis实现高可用的方案。由一个或者多个哨兵组成的哨兵系统可以用来监控一个或者多个主服务器,以及该主服务器下的所有从服务器。哨兵模式Redis服务器结构举例:
:-: ![哨兵模式举例](https://img-blog.csdnimg.cn/20210529194850711.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE4NDk5MA==,size_16,color_FFFFFF,t_70#pic_center)
**哨兵系统的主要作用是在主服务器宕机时进行故障排查,根据一定策略将从服务器指定为新的主服务器**。
```
备注:哨兵模式的之所以说是特殊的Redis服务器是因为哨兵模式的代码定义在sentinel.c,
并且定义了与redis.c中不同的命令支持。哨兵服务器只支持如下命令:
ping sentinel subscribe unsubscribe psubscribe punsubscribe publish info role
client shutdown auth hello acl command
```
## 启动哨兵模式
1. 创建sentiel.conf,并配置监视主机对象
```bash
# 设置要监控的主机,最后面的 1 是表示有多少台哨兵服务器认为该主机已经下线了就会启动故障恢复功能
sentinel monitor master1 127.0.0.1 6379 1
# 设置实例为10秒内无响应则被判断为主观下线
sentinel down-after-milliseconds master1 10000
# 在进行故障恢复操作时,可以同时对新的主服务器进行同步的从服务器的数量
sentinel parallel-syncs master1 1
# 刷新故障迁移状态的最大时限
sentinel failover-timeout master1 50000
```
主要配置:`sentinel monitor master_name ip port quorum`
其中quorum属性为判断主机为`客观下线`所需要的哨兵服务器的投票数量,即有quorum台哨兵已经认为它是`主观下线`了,就会将该主机判断为`客观下线`,接着进行故障恢复操作。
2. 启动哨兵服务器
如果有redis-sentinel的话可以直接使用命令
```bash
redis-sentinel sentinel.conf
```
如果没有的话可以使用命令
```bash
redis-server sentinel.conf --sentinel
```
![启动哨兵服务器](https://img-blog.csdnimg.cn/20210529195002549.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE4NDk5MA==,size_16,color_FFFFFF,t_70#pic_center)
哨兵的默认端口为`26379`
## 宕机检测机制
1. 检测**主观下线**状态
哨兵服务器会每秒一次的向主服务器、从服务器、其他哨兵发送ping命令,用来判断主服务器是否在线。在属性`down-after-milliseconds`设置的秒数内没有回应就会判断成`主观下线`。
2. 检测**客观下线**状态
当哨兵服务器检测到主服务器为主观下线状态,如果有其他哨兵服务器,则会像其他哨兵服务器发送信号询问`你是否也任务该主服务器已经主观下线了`。当同意(投票)数大于等于quorum设置的值,则会认为该主服务器真的宕机了,接着进行故障恢复。
例如在sentinel.conf中配置
```bash
sentinel monitor master1 127.0.0.1 6379 1
```
则当有一台哨兵服务器认为该服务器master1主观下线时就会进行故障恢复。
当配置
```bash
sentinel monitor master2 127.0.0.1 6380 5
```
则当有5台哨兵服务器认为master2主观下线时就会判断为客观下线,进行故障恢复操作。
## 故障转移
当主服务器master1被认定为客观下线时,领头的哨兵(在有多个哨兵的系统中会通过一定策略选取一台哨兵作为领头的哨兵进行故障恢复操作)会逐步进行如下操作,以下图的哨兵模式结构所示:
:-: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210529195146812.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE4NDk5MA==,size_16,color_FFFFFF,t_70#pic_center)
1. 在以下线的主服务器的从服务器中挑选出一台从服务器作为新的主服务器,选取的策略如下:
1. 不选处于断线、下线、最近5秒内没有回复哨兵的info命令的从服务器,同时不选与已下线的主服务连接断开超过**down-after-milliseconds * 10**的从服务器。
2. 接着选择优先级高的从服务器,从服务器的优先级在`slave-priority`或者(`replica-priority`不同版本不一样)属性中进行配置。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210529195208546.png#pic_center)
3. 优先级一样则选择复制偏移量replication_offset大的从服务器。
4. 复制偏移量一样则根据从服务器runid进行字典序排序,选择最小的runid。假设最终选择了slave1
*复制偏移量和从服务器runid详细可以看:
<a href="https://blog.csdn.net/weixin_44184990/article/details/117389980">《Redis主从复制》</a>*
5. 选择完毕之后,哨兵会向选择slave1服务器发送`slave no one`命令,将其提升为主服务器。
2 得到了新的主服务器之后,需要让master1中的其他从服务器都成为slave1的从服务器,这只需要向每台从服务器发送`slaveof ip port`即可。(*slaveof的详细过程可以看:<a href="https://blog.csdn.net/weixin_44184990/article/details/117389980"></a>《Redis主从复制》*)
3. 当master1重新上线时,需要将master1设置成slave1的从服务器。
按照示例最终哨兵模式结构如下:
:-: ![在这里插入图片描述](https://img-blog.csdnimg.cn/2021052919545149.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE4NDk5MA==,size_16,color_FFFFFF,t_70#pic_center)
通过上述故障恢复策略会选择一个数据保留比较完整的从服务作为主服务器,这个过程是在哨兵的监视下自动完成的,也就实现了在主服务器宕机下的Redis系统的高可用性。
【参考】
1. 《Redis设计与实现》第16章
- 第一章 Java基础
- ThreadLocal
- Java异常体系
- Java集合框架
- List接口及其实现类
- Queue接口及其实现类
- Set接口及其实现类
- Map接口及其实现类
- JDK1.8新特性
- Lambda表达式
- 常用函数式接口
- stream流
- 面试
- 第二章 Java虚拟机
- 第一节、运行时数据区
- 第二节、垃圾回收
- 第三节、类加载机制
- 第四节、类文件与字节码指令
- 第五节、语法糖
- 第六节、运行期优化
- 面试常见问题
- 第三章 并发编程
- 第一节、Java中的线程
- 第二节、Java中的锁
- 第三节、线程池
- 第四节、并发工具类
- AQS
- 第四章 网络编程
- WebSocket协议
- Netty
- Netty入门
- Netty-自定义协议
- 面试题
- IO
- 网络IO模型
- 第五章 操作系统
- IO
- 文件系统的相关概念
- Java几种文件读写方式性能对比
- Socket
- 内存管理
- 进程、线程、协程
- IO模型的演化过程
- 第六章 计算机网络
- 第七章 消息队列
- RabbitMQ
- 第八章 开发框架
- Spring
- Spring事务
- Spring MVC
- Spring Boot
- Mybatis
- Mybatis-Plus
- Shiro
- 第九章 数据库
- Mysql
- Mysql中的索引
- Mysql中的锁
- 面试常见问题
- Mysql中的日志
- InnoDB存储引擎
- 事务
- Redis
- redis的数据类型
- redis数据结构
- Redis主从复制
- 哨兵模式
- 面试题
- Spring Boot整合Lettuce+Redisson实现布隆过滤器
- 集群
- Redis网络IO模型
- 第十章 设计模式
- 设计模式-七大原则
- 设计模式-单例模式
- 设计模式-备忘录模式
- 设计模式-原型模式
- 设计模式-责任链模式
- 设计模式-过滤模式
- 设计模式-观察者模式
- 设计模式-工厂方法模式
- 设计模式-抽象工厂模式
- 设计模式-代理模式
- 第十一章 后端开发常用工具、库
- Docker
- Docker安装Mysql
- 第十二章 中间件
- ZooKeeper