概念介绍:
Sentinel(哨兵)是Redis的高可用性解决方案,主要是通过一个或多个Sentinel实例组成的Sentinel系统对任意多个主服务器以及这些主服务器的所有从服务器进行监视,当某个主服务器下线后,Sentinel系统自动将该主服务器下的某个从服务器升级为新的主服务器,然后由新的主服务器继续处理来自客户端的命令请求。Sentinel系统工作状况如下图所示:
当server1的下线时长超过用户设定的下线时长上限时,Sentinel系统就会对server1执行故障转义操作:
1 首先,Sentinel系统会挑选server1属下的一个从服务器,并将它升级为主服务器
2 随后,Sentinel系统会向server1的其它所有从服务器发送新的复制命令,让它们成为新的主服务器的从服务器,当所有从服务器开始复制新的主服务器时,故障转义操作执行完毕。
3 另外,Sentinel系统还会继续监视已经下线的server1,当它重新上线时,将他设置为新的主服务器的从服务器。
Sentinel系统进行故障转移的过程比较复杂,我们接下来一一介绍:
(一) 启动并初始化Sentinel
- 1.初始化服务器:
Sentinel本质上是一个运行在特殊模式下的redis服务器,它的特殊之处在于与普通的Redis服务器执行的工作是不同的,如下表所示列出了两者的功能点不同:
功能 | 使用情况 |
数据库和键值对方面额命令,比如Set、DEL、FLUSHDB | 不适用 |
事务命令,比如MULTI、WATCH | 不适用 |
脚本命令,比如EVAL | 不适用 |
RDB持久化命令,比如SAVE、BGSAVE | 不适用 |
AOF持久化命令,比如BGREWRITEOF | 不适用 |
复制命令,比如SLAVEOF | Sentinel内部可以使用,但是客户端不可以使用 |
发布与订阅命令,比如PUBLISH、SUBSCRIBE |
SUBSCRIBE、PSUBSCRIBE、UNSUBSCRIBE、PUNSUBSCRIBE四个命令 在Sentinel内部和客户端可以使用,但PUBLISH命令不可以在内部使用 |
文件事件处理器(负责发送命令请求、处理命令回复) | 在Sentinel内部使用,但关联的文件事件处理器和普通Redis服务器不同 |
事件事件处理器(负责执行serverCron函数) |
Sentinel内部使用,时间事件的处理器仍然是serverCron函数,serverCron函数 会调用sentinel.c/sentinelTimer函数,后者包含了sentinel要执行的所有操作 |
从上面表格可以看出Sentine是没有使用到数据库相关的功能的,因此在初始化的时候,不用载入RDB文件和AOF文件。
- 2.使用Sentinel专用代码:
普通服务器使用redis.h/REDIS_SERVERPORT常量的值作为服务器端口,而普通Redis服务器使用sentinel.c/REDIS_SENTINEL_PORT常量的值作为服务器端口。
此外普通服务器使用redis.c/redisCommandTable作为服务器的命令表,而Sentinel使用sentinel.c/sentinelcmds作为服务器的命令列表。
- 3 初始化sentinel状态
服务器初始化sentinel状态要做的工作就是初始化一个sentinel.c/sentinelState结构(简称“sentinel状态”),该结构保存了所有与sentinel功能有关的状态。sentinelState结构如下图所示:
- 4 初始化Sentinel状态的master属性
Sentinel状态的masters字典记录了所有被监视的主服务器相关的信息,其中:字典的键是被监视主服务器的名字,字典键对应的值是被监视主服务器对应的sentinel.c/sentinelRedisInstance的结构,sentinelRedisInstance可以对应主服务器,从服务器,或者另外一个sentinel。sentinelRedisInstance的结构如下图所示:
Sentinel状态的初始化将引发对masters字典的初始化,而masters字典的初始化是根据被载入的Sentinel配置文件进行的。
- 5 创建连向主服务器的网络连接:
初始化sentinel的最后一步是创建连向被监视主服务器的网络连接,用以发送命令与从命令回复中获取信息。sentinel会创建两个连向主服务器的连接:
一个是命令链接,该连接专门用于向主服务器发送命令,并接受命令回复。
另一个是订阅连接,该连接专门用于订阅主服务器的_sentinel_:hello频道。
(二) 获取主服务器信息
Sentinel默认以每十秒一次的频率,通过命令连接向主服务器发送INFO命令,并通过分析命令回复获取主服务器器的信息。获取的信息主要有如下两个方面:
1 关于服务器本身的信息,比如run_id域记录的服务器运行id,以及role域记录的服务器角色。
另一方面,获取关于主服务器下所有的从服务器信息,每个从服务器都有一个slave字符串开头的行记录,每行的ip=域记录了从服务器的的IP地址,port==域记录了从服务器的端口号。根据IP地址和port端口,sentinel无须用户提供从服务器的地址信息,就可以自动发现从服务器的。
sentinel根据主服务器的run_id和role域的信息,将对主服务器的实力结构进行更新,如果run_id不同,比如主服务器重启,则会对实例结构更新。而主服务器返回的从服务器信息,如果已经存在,则进行更新,会在slaves字典中为这个主服务器创建一个新的实例结构。
(三)获取从服务器信息
当sentinel发现主服务器有新的从服务器时,除了在为这个主服务器创建一个新的从服务器实例结构之外。还会创建连接到从服务器的命令连接以及订阅连接。之后会默认每十秒通过命令连接向从服务器发送Info命令,并通过命令回复提取一下信息,并根据这些信息对从服务器的实力结构进行更新。
1 从服务器的运行ID run_id
2 从服务器的角色role
3 主服务器的IP地址master_host,以及master_port
4 主从服务器的连接状态master_link_status
5 从服务器的优先级slave_priority
6 从服务器的复制偏移量slave_repl_offset
(四)向主服务器和从服务器发送信息
默认情况下,sentinel会每两秒,通过命令连接向所有被监视的主服务器和从服务器发送一下格式的命令:
PUBLISH __sentinel__:hello "<s_ip>,<s_port>,<s_runid>,<s_epoch>,<m_name>,<m_ip>,<m_port>,<m_epoch>"
标签:初始化,命令,REDIS,哨兵,sentinel,集群,服务器发送,Sentinel,服务器 From: https://www.cnblogs.com/mtjb1dd/p/16632493.html