一.概述

  Sentinel(哨岗或哨兵)是Redis的高可用解决方案:由一个或多个Sentinel实例(instance)组成的Sentinel系统(system)可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。

  1.1 下面是一个Sentinel系统与主从服务器之间的关系:

    (1) 双环图案的server1是当前的主服务器,以及server2、server3、server4三个从服务器。

    (2) 三个从服务器复制主服务器的写入命令数据,实现数据同步。

    (3) Sentinel系统则监视所有四个服务器。

  1.2  Sentinel系统监视主服务器下线

    当主服务器server1进入下线状态,那么三个从服务器复制操作被中止,由Sentinel系统监视到了server1已下线,当server1的下线时长超过用户设定的下线时长时,Sentinel系统就会对server1执行自动故障迁移。下面是Sentinel系统监视到了server1主服务器已下线:

    只有具备故障转移功能,才是一个高可用的解决方案。Sentinel系统自动执行故障转移步骤:

    (1) 首先Sentinel系统会挑选一个从服务器,并将这个选中的从服务器升级为新的主服务器。 

    (2) 之后 Sentinel系统会让所有从服务器都开始复制新的主服务器,故障转移操作执行完毕。

    (3) Sentinel系统还会继续监视已下线的server1,并在它重新上线时,将它设置为从服务器。

二. Sentinel服务器初始化过程介绍

   2.1 初始化一个普通的Redis服务器

    因为Sentinel服务器本质上只是一个运行在特殊模式下的Redis服务器,所以启动Sentinel的第一步,就是初始化一个普通的Redis服务器。初始化服务器在介绍“服务器章节”中讲到过。由于工作不同,Sentinel的初始化过程和普通Redis服务器的初始化过程并不完全相同。比如:Sentinel就不会载入RDB文件或者AOF文件。下面表格展示Sentinel模式下运行时,服务器各个主要功能使用情况:

功能 使用情况
数据库和键值对方面的命令,如set,del,flushdb 不使用
事务命令,如multi和watch 不使用
脚本命令,如eval 不使用
RDB持久化命令,如save和bgsave 不使用
AOF 持久化命令,如bgrewriteaof 不使用

复制命令,如slaveof

Sentinel内部可以使用,但客户端不可以使用
发布与订阅命令,如publish和subscribe Subscribe,psubscribe,unsubscribe,punsubscribe四个命令在Sentinel内部和客户端都可以使用,但publish命令只能在Sentinel内部使用
文件事件处理器,(负责发送命令请求,处理命令回复) Sentinel内部使用,但关联的文件事件处理器与普通Redis服务器不同
时间事件处理器,(负责执行serverCron函数) Sentinel内部使用,serverCron函数会调用sentinel.c/sentinelTimer函数,后者包含了Sentinel要执行的所有操作

  

  2.2 服务器内部使用Sentinel专用代码

    启动Sentinel的第二个步骤就是将一部分普通Redis服务器使用的代码替换成Sentinel专用代码。比如:普通Redis服务器端口6379,而Sentinel端口26379,即Sentinel.c/redis_sentinel_port常量。还有命令表也不一样,对于Sentinel的客户端就只有ping, sentinel,info, Subscribe,psubscribe,unsubscribe,punsubscribe 这7个命令,即Sentinel.c/sentinelcmds作为服务器的命令表。

  

  2.3 初始化Sentinel状态

    应用了专用代码之后,步骤三是服务器会初始化一个Sentinel.c/sentinelstate结构,这个结构保存了服务器中所有和Sentinel功能有关的状态,对于服务器一般状态还是由redis.h/redisServer结构保存。

  2.4 初始化Sentinel状态的masters属性

    sentinel状态中的masters字典记录了所有被sentinel监视的主服务器的相关信息,其中字典的键是被监视的主服务器名字,而字典的值是被监视主服务器对应的sentinel.c/sentinelRedisInstance结构。每个sentinelRedisInstance实例结构代表监视一个Redis服务器实例,这个实例可以是主服务器,也可以是从服务器,或者另外一个sentinel服务器。对于sentinel状态的初始化将引发对masters字典的初始化,而masters字典的初始化是根据被该入的sentinel配置文件(sentinel.conf)来进行的。

  2.5 创建连向主服务器的网络连接

    初始化Sentinel的最后一步是创建连向被监听主服务器的网络连接,Sentinel将成为主服务器的客户端,它可以向主服务器发送命令,并从命令回复中获取相关信息。对于被Sentinel监视的主服务器来说,Sentinel会创建两个连向主服务器的异步网络连接

    (1) 一是命令连接,专门用于向主服务器发送命令,并接收命令回复。比如sentinel向主服务器发送:info命令。

    (2) 二是订阅连接,专门用于订阅主服务器的_sentinel_:hello频道。 比如sentinel向主,从,其它sentinel发送sentinel本身和主库信息。

    下面是一个Sentinel监视两个主服务器master1和master2,创建命令连接和订阅连接图:

      命令连接:是sentinel用来对主服务器发送命令,以此来与主服务器进行通信,所以sentinel必须向主服务器创建命令连接。订阅连接:是redis在发布与订阅功能 中,被发送的信息都不会保存在redis服务器中,如果信息发送时,想要接收的客户端不在线或者断线,那么这个客户端就会丢失这条信息,因为为了不丢失_sentinel_:hello频道的任何信息,sentinel必须专门用一个订阅连接来接收该频道的信息。

      

三. 获取服务器信息

  3.1 Sentinel获取主服务器信息

    Sentinel默认会以每10秒一次的频率,通过命令连接向主服务器发送info命令,通过分析info命令的回复来获取主服务器的当前信息,就像在上篇讲到的复制功能,在客户端输入info replication 命令一样,Sentinel可以获取以下两方面的信息:

    (1) 关于主服务器本身的信息,包括服务器run_id,role的服务器角色。

    (2) 关于所有从服务器的信息,每个从服务器都由一个slave字符串开头的行记录,记录了从服务器IP和端口(主服务器中有从库的配置信息)。

  3.2 Sentinel获取从服务器信息

    当Sentinel发现主服务器有新的从服务器出现时,Sentinel除了会为这个新的从服务器创建相应的实例结构(sentinelRedisInstance)之外,Sentinel还会创建连接到从服务器的命令连接和订阅连接。Sentinel默认会以每10秒一次的频率通过命令连接从服务器发送info命令,通过分析info命令的回复来获取从服务器的当前信息。包括:从服务器运行run_ID、从服务器角色role、主服务器的ip及端口、主从服务器的连接状态master_link_status、从服务器的优先级slave_priority。

  3.3  Sentinel向主从服务器发送信息

    在默认情况下, Sentinel会以每2秒一次的频率,通过命令连接向,所有被监视的主服务器和从服务器发送以下格式的命令:

    

    这条命令向服务器的_sentinel_:hello频道发送了一条信息,信息的内容由多个参数组成:

    (1) 以s_开头以参数记录的是sentinel本身的信息。

    (2) 而m_开头的参数记录的则是主服务器的信息,如果sentinel正在监视的是主服务器,那么这些参数就是主服务器的信息,如果sentinel正在监视的是从服务器,那么这些参数记录就是从服务器正在复制的主服务器的信息。

参数 描述
S_ip Sentinel的ip地址
S_port Sentinel的端口号
S_runid Sentinel的运行ID

S_epoch

Sentinel 的当前配置纪元

m_name 主服务器的名字
M_ip 主服务器的IP地址
M_port 主服务器的端口号
M_epoch 主服务器的当前配置纪元

    以下是一条sentinel通过publish命令向主服务器发送的信息示例:

  

    这个示例中sentinel的ip地址为172.0.0.1端口号为26379, 运行ID为后面一串,当前纪元为0。主服务器的名字为mymaster,ip地址为127.0.0.1,端口号为6379, 当前纪元为0。

  3.4  sentinel接收来自主服务器和从服务器的频道信息

    当sentinel与一个主服务器或者从服务器建立起订阅连接之后,Sentinel就会通过订阅连接,向服务器发送以下命令:subscribe_sentinel_:hello 。对于每个与Sentinel连接的服务器,Sentinel既通过命令连向服务器的_sentinel_:hello频道发送信息,又通过订阅连接从服务器的_sentinel_:hello频道接收信息。

    当有三个sentinel,分别是sentinel1、sentinel2 、sentinel3。三个sentinel在监视同一个服务器,那么当sentinel1向服务器的_sentinel_:hello频道发送一条信息时,所有订阅了_sentinel_:hello频道的sentinel(包括sentinel1自己在内)都会收到这条信息。

    当一个sentinel从_sentinel_:hello频道收到一条信息时,sentinel会对这条信息进行分析,提取出信息中sentinel 的 ip 、port、runID等8个参数,并进行以下检查:

    (1) 如果信息中记录的sentinel运行ID和接收信息的sentinel运行ID相同,那么说明这条信息是sentinel自己发送的,sentinel将丢弃这条信息,不做进一步处理。

    (2) 相反地,如果信息中记录的sentinel运行ID和接收信息的sentinel运行ID不相同,那说明这条信息监视同一个服务器的其它sentinel发来的,接收信息的sentinel将根据信息中的参数,对相应主服务器的实例结构进行更新。

  3.5 sentinel更新自己的sentinels字典

    sentinel为主服务器创建实例结构中的sentinels字典,保存了sentinel本身,还监视这个主服务器的其他sentinel的资料。当一个sentinel接收到其他sentinels发来的信息时,接收的sentinel会从信息中分析并提取出两方面参数:

    (1)与sentinel有关的参数,包括sentinel的ip、port、runid、配置纪元。

    (2)与主服务器有关的参数, 包括监视主服务器的ip、port、runid、配置纪元。

    假设分别有三个sentinel: 127.0.0.1:26379、127.0.0.1:26380、127.0.0.1:26381。三个sentinel正在监视主服务器127.0.0.1:6379, 那么当127.0.0.1:26379这个sentinel接收到以下消息时:

    这个sentinel将执行以下动作:

    (1) 第一条信息发送者为自己,信息忽略。

    (2) 第二条信息发送者为26381, sentinel会根据信息提取出内容,对sentinels字典中26381对应的实例结构进行更新。

    (3) 第三条信息发送者为23680,同样更新字典中的23680对应的实例结构。

    每个sentinel都有自己的一个sentinels字典, 对于26379的sentinel它的sentinels字典信息保存了26380和26381两个sentinel信息。其它sentinel也一样。

  3.6 sentinel创建连向其他sentinel的命令连接

    当sentinel通过频道信息发现一个新的sentinel时,不仅更新sentinels字典,还会创建一个连向sentinel命令连接,而新的sentinel也会创建连向这个sentinel的命令连接,最终监视同一个主服务器的多个sentinel将形成相互连接的网络。如下图所示:

redis 系列23 哨兵Sentinel (上)的更多相关文章

  1. redis 系列25 哨兵Sentinel (高可用演示 下)

    一. Sentinel 高可用环境准备 1.1 Sentinel 集群环境 环境 说明 操作系统版本 CentOS  7.4.1708  IP地址 172.168.18.200 网关Gateway 1 ...

  2. redis 系列24 哨兵Sentinel (中)

    四. 检测下线状态 对于Redis的Sentinel中关于下线有两个不同的概念:(1)主观下线(Subjectively Down, 简称 Sdown) 指的是单个 Sentinel 实例对服务器做出 ...

  3. Redis 主从、哨兵Sentinel、Jedis

    Redis 主从.哨兵Sentinel.Jedis 2017年02月15日 15:52:48 有且仅有 阅读数 6183 文章标签: redis主从sentineljedis 更多 分类专栏: 7/1 ...

  4. redis系列--深入哨兵集群

    一.前言 在之前的系列文章中介绍了redis的入门.持久化以及复制功能,如果不了解请移步至redis系列进行阅读,当然我也是抱着学习的知识分享,如果有什么问题欢迎指正,也欢迎大家转载.而本次将介绍哨兵 ...

  5. redis系列:哨兵

    1 简介 Sentinel(哨兵)是Redis 的高可用性解决方案:通过哨兵可以创建一个当主服务器出现故障时自动将从服务器升级为主服务器的一个分布式系统.解决了主从复制出现故障时需要人为干预的问题. ...

  6. Redis系列五 - 哨兵、持久化、主从

    问:骚年,都说Redis很快,那你知道这是为什么吗? 答:英俊潇洒的面试官,您好.我们可以先看一下 关系型数据库 和 Redis 本质上的区别. Redis采用的是基于内存的,采用的是单进程单线程模型 ...

  7. redis 系列21 复制Replication (上)

    一.   概述 使用和配置主从复制非常简单,每次当 slave 和 master 之间的连接断开时, slave 会自动重连到 master 上,并且无论这期间 master 发生了什么, slave ...

  8. 【目录】redis 系列篇

    随笔分类 - redis 系列篇 redis 系列27 Cluster高可用 (2) 摘要: 一. ASK错误 集群上篇最后讲到,对于重新分片由redis-trib负责执行,关于该工具以后再介绍.在进 ...

  9. Redis系列4:高可用之Sentinel(哨兵模式)

    Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 1 背景 从第三篇 Redis系列3:高可用之主从架构 ,我们知道,为Re ...

随机推荐

  1. Nastya Is Buying Lunch

    At the big break Nastya came to the school dining room. There are nn pupils in the school, numbered ...

  2. Mac下brew安装JDK的教程

    ---恢复内容开始--- 安装命令: brew cask install java 默认应该会下载jdk7 也可以指定下载版本brew cask install java6 注意: brew inst ...

  3. Unity Rain Ai 插件基本使用(二)

    前言 在前面的教程中我们已经基本实现了路径导航和障碍物规避. 但是这样我们并没有让我们的角色学会思考,他只是机械的去完成一些步骤,这并不能体现Rain插件的智能. 一个角色他应该有多个不同的状态,待机 ...

  4. Spring Cloud微服务笔记(二)Spring Cloud 简介

    Spring Cloud 简介 Spring Cloud的设计理念是Integrate Everything,即充分利用现有的开源组件, 在它们之上设计一套统一的规范/接口使它们能够接入Spring ...

  5. PHP生成指定随机字符串的简单实现方法

    /** * @param string $type * @param $length * @return string */ function randomString($type="num ...

  6. redis + cookies 实现持久登入

    通过登入把用户信息和token加载到redis中去, 将token和部分用户信息存储在cookie中, 下次登入时 判断cookie的token在redis中是否存在, 存在就把用户信息加载出来自动登 ...

  7. ajaj简介

    1. 什么是ajax? ajax的全称 Asynchronous(异步) JavaScript and XML. ajax是一种用于创建快速动态网页的技术. 主要用于前后台的交互,在前后台的交互中还有 ...

  8. HTML入门10

    目前,掌握了图像,视频和音频的嵌入,下面来谈iframe和embed.object嵌入网页, 嵌入简史,刚开始流行用嵌入框架然后不同部分显示i不同内容,可以解决下载速度慢时的问题: 慢慢的插件技术流行 ...

  9. 微信测试号开发入门配置问题java

    这个测试号配置弄了好几天了,入了无数坑,终于解决了...辛苦我了,手动安慰一下自己.. 为了萌新们以后不要再浪费时间绕半天做无用功.看看楼楼的艰苦历程吧. 此教程针对没有云服务器,没有自己的域名的.没 ...

  10. apidoc @apiGroup兼容中文

    1.找到安装目录 中 api_group.js C:\Users\ZhiJiao361\AppData\Roaming\npm\node_modules\apidoc\node_modules\api ...