模式二:哨兵模式

上一篇问讲述了redis集群的主从模式,这一篇我们讲述哨兵模式。

Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:

  • 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
  • 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
  • 自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

这个就相比于主从系统更加的灵活化,主从系统一旦主节点崩溃,整个系统写的功能就丧失。

Redis Sentinel 是一个分布式系统, 你可以在一个架构中运行多个 Sentinel 进程(progress), 这些进程使用流言协议(gossip protocols)来接收关于主服务器是否下线的信息, 并使用投票协议(agreement protocols)来决定是否执行自动故障迁移, 以及选择哪个从服务器作为新的主服务器。

哨兵进程工作方式:

  1. 每个Sentinel(哨兵)进程以每秒钟一次的频率向整个集群中的Master主服务器,Slave从服务器以及其他Sentinel(哨兵)进程发送一个 PING 命令。
  2. 如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 那么这个实例会被 Sentinel 标记为主观下线。 一个有效回复可以是: +PONG 、 -LOADING 或者 -MASTERDOWN 。
  3. 如果一个主服务器被标记为主观下线, 那么正在监视这个主服务器的所有 Sentinel 要以每秒一次的频率确认主服务器的确进入了主观下线状态。
  4. 如果一个主服务器被标记为主观下线, 并且有足够数量的 Sentinel (至少要达到配置文件指定的数量)在指定的时间范围内同意这一判断, 那么这个主服务器被标记为客观下线。
  5. 在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有主服务器和从服务器发送 INFO 命令。 当一个主服务器被 Sentinel 标记为客观下线时, Sentinel 向下线主服务器的所有从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次。
  6. 只要一个 Sentinel 发现某个主服务器进入了客观下线状态, 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对失效的主服务器执行自动故障迁移操作。
  7. 当没有足够数量的 Sentinel 同意主服务器已经下线, 主服务器的客观下线状态就会被移除。 当主服务器重新向 Sentinel 的 PING 命令返回有效回复时, 主服务器的主观下线状态就会被移除。

主观下线以及客观下线解释

主观下线(Subjectively Down, 简称 SDOWN)指的是单个 Sentinel 实例对服务器做出的下线判断。

客观下线(Objectively Down, 简称 ODOWN)指的是多个 Sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断。

从主观下线状态切换到客观下线状态并没有使用严格的法定人数算法(strong quorum algorithm), 而是使用了流言协议: 如果 Sentinel 在给定的时间范围内, 从其他 Sentinel 那里接收到了足够数量的主服务器下线报告, 那么 Sentinel 就会将主服务器的状态从主观下线改变为客观下线。 如果之后其他 Sentinel 不再报告主服务器已下线, 那么客观下线状态就会被移除。

客观下线条件只适用于主服务器: 对于任何其他类型的 Redis 实例, Sentinel 在将它们判断为下线前不需要进行协商, 所以从服务器或者其他 Sentinel 永远不会达到客观下线条件。

Sentinel是如何发现其他的Sentinel 和从服务器的?

  1. 每个 Sentinel 会以每两秒一次的频率, 通过发布与订阅功能, 向被它监视的所有主服务器和从服务器的 sentinel:hello 频道发送一条信息, 信息中包含了 Sentinel 的 IP 地址、端口号和运行 ID (runid)。
  2. 每个 Sentinel 都订阅了被它监视的所有主服务器和从服务器的 sentinel:hello 频道, 查找之前未出现过的 sentinel (looking for unknown sentinels)。 当一个 Sentinel 发现一个新的 Sentinel 时, 它会将新的 Sentinel 添加到一个列表中, 这个列表保存了 Sentinel 已知的, 监视同一个主服务器的所有其他 Sentinel 。
  3. Sentinel 发送的信息中还包括完整的主服务器当前配置(configuration)。 如果一个 Sentinel 包含的主服务器配置比另一个 Sentinel 发送的配置要旧, 那么这个 Sentinel 会立即升级到新配置上。
  4. 在将一个新 Sentinel 添加到监视主服务器的列表上面之前, Sentinel 会先检查列表中是否已经包含了和要添加的 Sentinel 拥有相同运行 ID 或者相同地址(包括 IP 地址和端口号)的 Sentinel , 如果是的话, Sentinel 会先移除列表中已有的那些拥有相同运行 ID 或者相同地址的 Sentinel , 然后再添加新 Sentinel 。

从上述我们可以看出哨兵之间的互相发现以及发现从服务器,都是通过发布订阅的功能来实现的,既我们之前所讲的redis的发布订阅。当有一个新的哨兵加入进来就会向频道中发送自己的信息,其他所有订阅的哨兵会通过消费信息添加新的哨兵信息。

自动故障迁移过程:

  • 发现主服务器已经进入客观下线状态。
  • 在失效主服务器属下的从服务器当中, 那些被标记为主观下线、已断线、或者最后一次回复 PING 命令的时间大于五秒钟的从服务器都会被淘汰。
  • 在失效主服务器属下的从服务器当中, 那些与失效主服务器连接断开的时长超过 down-after 选项指定的时长十倍的从服务器都会被淘汰。
  • 在经历了以上两轮淘汰之后剩下来的从服务器中, 我们选出复制偏移量(replication offset)最大的那个从服务器作为新的主服务器; 如果复制偏移量不可用, 或者从服务器的复制偏移量相同, 那么带有最小运行 ID 的那个从服务器成为新的主服务器。
  • 向被选中的从服务器发送 SLAVEOF NO ONE 命令,让它转变为主服务器。
  • 通过发布与订阅功能, 将更新后的配置传播给所有其他 Sentinel , 其他 Sentinel 对它们自己的配置进行更新。
  • 向已下线主服务器的从服务器发送 SLAVEOF 命令, 让它们去复制新的主服务器。
  • 当所有从服务器都已经开始复制新的主服务器时, 领头 Sentinel 终止这次故障迁移操作。

上述简单讲述了: - Sentinel是如何发现其他的Sentinel 以及从服务器 - Sentinel是如何判断主服务器主观下线以及客观下线的 - Sentinel是如何自动故障迁移的

下面我们将具体的搭建哨兵模式

首先我们像搭建主从模式一样,搭建出主从并启动,如上一篇文章一样,这里我们主节点为:6380端口,从节点为6381端口,如图所示:

启动主从后,6380redis文件中创建哨兵模式所需要的配置文件,需要启动几个哨兵就创建几个配置文件,如图:

配置文件内容如下:

如上就是我们需要的全部配置,现在我们开始启动两个哨兵。

启动命令为 redis-service sentinel.conf --sentinel

首先启动端口号为26379的哨兵,如图:

启动端口号为26380的哨兵,如图:

此时我们查看主节点服务的模式也是哨兵模式。

并且我们可以看到两个哨兵启动成功后,两个哨兵的配置文件也有所变化:

可以看到两个配置文件都自动添加了从节点以及另一个哨兵的信息。

此时我们的redis哨兵模式就创建成功了,后面我们测试主节点断开及主节点恢复的时候和java代码结合演示。

我们要整合哨兵模式,首先要修改redis的配置文件。如下:

@Component
@Slf4j
public class JedisConfig {@Value("${spring.redis.host}")private String host;@Value("${spring.redis.port}")private int port;@Value("${spring.redis.timeout}")private int timeout;@Value("${spring.redis.pool.max-active}")private int maxActive;@Value("${spring.redis.pool.max-idle}")private int maxIdle;@Value("${spring.redis.pool.min-idle}")private int minIdle;@Value("${spring.redis.pool.max-wait}")private long maxWaitMillis;@Beanpublic JedisSentinelPool redisPoolFactory(){JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();jedisPoolConfig.setMaxIdle(maxIdle);jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);jedisPoolConfig.setMaxTotal(maxActive);jedisPoolConfig.setMinIdle(minIdle);//此处配置的哨兵信息,切记不要配置主节点地址,这样故障迁移的时候才能切换过来。Set<String> sentinels = new HashSet<String>(Arrays.asList("127.0.0.1:26379","127.0.0.1:26380"));
//      JedisPool jedisPool = new JedisPool(jedisPoolConfig,host,port,timeout,null);JedisSentinelPool jedisPool = new JedisSentinelPool("mymaster",sentinels,jedisPoolConfig);log.info("JedisPool注入成功!");log.info("redis地址:" + host + ":" + port);return  jedisPool;}}

并将RedisClient中连接池修改:

//@Resource//private JedisPool jedisPool;@Resourceprivate JedisSentinelPool jedisPool;这个具体配置之前文章中有详细内容

我们先测试一下哨兵模式是否连接正常

@Testpublic   void setRedis()  {try {redisClient.set("testSentinel5","aaaa");} catch (Exception e) {e.printStackTrace();}}

运行结果:

可以看到连接正常,那么我们现在将主节点关掉,测试一下故障迁移。

从上图我们可以看出在6380主节点断开后,6381从节点讲过哨兵的故障迁移变为了主节点。

并且我们可以看到原先加在6381从节点redis.windows.conf配置文件中的slaveof配置以及自动删除了,而且两个哨兵中的主节点监控也由6380变为了6381.

我们再测试一下迁移后的写入功能。

@Testpublic   void setRedis()  {try {redisClient.set("testSentinel6","aaaa");} catch (Exception e) {e.printStackTrace();}}

可以看出在主节点断开后,集群的写入查看功能正常。

接下来我们将6380恢复,看是否能够重新连接入集群:

可以看到6380重新开启后,自动变为从节点连接入集群,并在6380的redis.windows.conf的配置文件中自动加入了:

slaveof 10.66.205.85 6381

今天就写到这里了,Redis的哨兵模式是以主从模式为基础的,所以说,主从模式拥有的一些缺点,在哨兵模式下也具有。哨兵模式主要是监控Master主服务器的运行情况,当然也会监控Slave从服务器的运行情况,如果Master主服务器发生了故障,该模式可以保证Slave从服务器顺利升级为Master主服务器继续提供服务,以此提高系统的高可用性。虽然哨兵模式比主从模式提高了不少系统的高可用性,但是该模式不能水平扩容,不能动态的增、删节点,这也是限制哨兵模式广泛应用的主要原因。Redis也看到了这个情况,所在在Redis的3.x以后的版本提供了一个更加强大集群模式,那就是Cluster集群模式,这个模式也是我们下一篇文章的主题。

down redis集群_Redis总结(十)redis集群-哨兵模式相关推荐

  1. 陈艾盐:春燕百集访谈节目第二十六集

    <春燕姐姐>访谈节目共120集,每月分10集播出,记录了上百位企业家对"慈善"的各种不同见解,通过讲述社会真善美的故事,让更多的人了解慈善.发扬慈善精神,构建更加美好, ...

  2. 陈艾盐:春燕百集访谈节目第十九集

    <春燕姐姐>访谈节目共120集,每月分10集播出,记录了上百位企业家对"慈善"的各种不同见解,通过讲述社会真善美的故事,让更多的人了解慈善.发扬慈善精神,构建更加美好, ...

  3. 陈艾盐:春燕百集访谈节目第二十五集

    <春燕姐姐>访谈节目共120集,每月分10集播出,记录了上百位企业家对"慈善"的各种不同见解,通过讲述社会真善美的故事,让更多的人了解慈善.发扬慈善精神,构建更加美好, ...

  4. Redis进阶实践之二十 Redis的配置文件使用详解

    一.引言 写完上一篇有关redis使用lua脚本的文章,就有意结束Redis这个系列的文章了,当然了,这里的结束只是我这个系列的结束,但是要学的东西还有很多.但是,好多天过去了,总是感觉好像还缺点什么 ...

  5. Redis 高级特性(5)— 集群模式(主从模式、哨兵模式、cluster 集群模式)

    Redis 是如何做到高可用的呢? 它主要通过支持主从模式.哨兵模式.集群模式这三种模式,来满足不同业务特点和可用等级的需求. 其中,主从模式部署最简单,用得也最多,集群模式比较复杂,但可用性最高. ...

  6. redis lettuce 超时_Spring Cache 操作 Redis 实现数据缓存(上)

    点击上方☝SpringForAll社区 轻松关注!及时获取有趣有料的技术文章 本文来源:http://www.mydlq.club/article/55/ . 一.缓存概念知识 . 1.是什么缓存 . ...

  7. 两台服务器安装redis集群_Redis Cluster搭建高可用Redis服务器集群

    一.Redis Cluster集群简介 Redis Cluster是Redis官方提供的分布式解决方案,在3.0版本后推出的,有效地解决了Redis分布式的需求,当一个节点挂了可以快速的切换到另一个节 ...

  8. redis 集群搭建_Redis分布式缓存分布式集群搭建

    当你试图解决一个你不理解的问题时,复杂化就产成了.-Andy Boothe Redis集群安装部署 Redis是一个运行在内存的非关系型数据库,因为其速度快(效率高),支持数据的持久化(安全),事务操 ...

  9. redis 集群 分片 扩容_Redis高可用之集群实现原理

    概要:本文主要用于介绍Redis集群实现的原理,以及集群中的主从切换.副本漂移.分片迁移的原理 1 Redis集群实现的原理 集群是用来提供横向扩展能力,即当数据量增多以后,通过增加服务节点就可以扩展 ...

最新文章

  1. ThinkPHP下隐藏index.php以及URL伪静态
  2. 【web安全】Spring boot heapdump获取敏感信息
  3. 当 TiDB 与 Flink 相结合:高效、易用的实时数仓
  4. decode and nvl and sign
  5. WebStorm Vue ElementUI
  6. 财务系统专用服务器中标公告,东南大学财务处服务器存储-招标办公室.doc
  7. python怎么启动mne_mne-python学习之一 入门介绍
  8. 程序员上班都在做什么?
  9. sorted是python的内置函数吗_Python中的内置sorted()函数
  10. centos标准分区调整大小_磁盘怎么调整分区大小 磁盘调整分区大小教程【详细步骤】...
  11. linux网络调试发包抓包工具
  12. Hololens开发学习笔记——海康摄像头直播视频流
  13. 机器人学从理论、设计到建模仿真零基础入门教程(硬核、偏零基础)
  14. C语言pow函数编写
  15. c语言编程高斯白噪声信号,关于产生高斯白噪声
  16. 问题 Q(1208): 【基础算法】倒酒问题
  17. 中国新出海故事:人、疫情与纽带
  18. HTML学生个人网站作业设计:电影网站设计——电影购票项目(9页) HTML+CSS+JavaScript 简单DIV布局个人介绍网页模板代码 DW学生个人网站制作成品下载
  19. Python中mechanize库的简单使用说明
  20. Oracle基础教程

热门文章

  1. android 消除标题,Android Activity 去掉标题栏及全屏显示
  2. lingo变量无限制版本_【运筹学】用Lingo求解运输问题,兼谈Lingo语法
  3. mysql存储过程中文乱码_mysql存储过程碰到中文乱码问题
  4. arm Linux 中断管理机制
  5. C/Cpp / 设计模式 / 观察者模式
  6. 为什么尽量使用常量引用
  7. windows10mysql安装包_windows10上安装mysql8(zip包)
  8. MT7628/MT7688 修改串口2作为调试串口 所踩的坑
  9. oracle 10g rac 修改sga_target不生效,关于请教rac的sga 设置及修改问题
  10. Zabbix学习之路(一)之Zabbix安装