当前位置:   article > 正文

Redis中的Sentinel(一)

Redis中的Sentinel(一)

Sentinel

概述

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

例子

  • 举个例子。图中展示了一个Sentinel系统监视服务器的例子其中:
    1.用双环图案表示的是当前的主服务器server1
    2.用单环图表示的是主服务器的三个从服务器server2、server3以及server4
    3.server2、server3、server4三个从服务器正在复制主服务器server1,而Sentinel系统则在监视所有四个服务器
    在这里插入图片描述
  • 假设这时,主服务器server1进入下线状态,那么从服务器server2、server3、server4对主服务器的复制操作将被中止,并且Sentinel系统会察觉到server1已下线,如图所示(下线的服务器用虚线表示)
    在这里插入图片描述
  • 当server1的下线时长超过用户设定的下线时长上限时,Sentinel系统就会对
    server1执行故障转义操作:
    1.首先,Sentinel系统会挑选server1属下的其中一个从服务器,并将这个被选中的
    从服务器升级为新的主服务器
    2.之后,Sentinel系统会向server1属性的所有从服务器发送新的复制指令,让它们称为新的主服务器的从服务器,当所有从服务器都开始复制新的主服务器时,故障转移操作执行完毕
    3.另外,Sentinel还会继续监视已下线的server1,并在它重新上线时,将它设置为新的
    主服务器的从服务器
    在这里插入图片描述

如图所示。Sentinel将系统2升级为新的主服务器,并让服务器server3和server4成为
sever2的从服务器的过程,之后,如果server1重新上线的话,它将被Sentinel系统降级
为server2的从服务器
在这里插入图片描述

启动并初始化Sentinel

redis-sentinel /path(你自己的路径)/sentinel.conf
  • 1

或者

redis-server /path(你自己的路径)/sentinel.conf -- sentinel
  • 1

这两个命令的效果完全相同。
当一个Sentinel启动时,他需要执行以下步骤:

  • 1.初始化服务器
  • 2.将普通Redis服务器使用的代码替换成Sentinel专用代码
  • 3.初始化Sentinel状态
  • 4.根据给定的配置文件,初始化Sentinel的监视主服务器列表。}
  • 5.创建连向主服务器的网络连接

初始化服务器。

首先,因为Sentinel本质上只是一个运行在特殊模式下的Redis服务器,所以启动Sentinel的第一步,就是初始化一个普通的Redsi服务器,不过因为Sentinel执行的工作和普通Redis服务器执行的工作不同,
所以Sentinel的初始化过程和普通Redis服务器的初始化过程并不完全相同。例如,普通服务器在初始化时会通过载入RDB文件或者AOF文件来还原数据库状态,但是因为Sentinel并不使用数据库,所以初始化Sentinel时就不会载入RDB文件或者AOF文件
在这里插入图片描述

使用Sentinel专用代码。

启动Sentinel的第二个步骤就是将一部分普通Redis服务器使用的代码替换成Sentinel专用代码。比如说,普通Redis服务器使用redis.h/REDIS_SERVERPORT常量的值作为服务器端口:

#define REDIS_SERVERPORT 6379
  • 1

而Sentinel则使用sentinel.c/REDIS_SENTINEL_PORT常量的值作为服务器端口:

#define REDIS_SENTINEL_PORT 26379
  • 1

除此之外,普通Redis服务器使用redis.c(6.0版本以上可能在server.c)/redisCommandTable作为服务器的命令表:

struct redisCommand redisCommandTable[] = {
    {"get",getCommand,2,"read-only fast @string",0,NULL,1,1,1,0,0,0},
{"getex",getexCommand,-2,"write fast @string",0,NULL,1,1,1,0,0,0},
{"set",setCommand,-3,"write use-memory @string",0,NULL,1,1,1,0,0,0},
{"setnx",setnxCommand,3,
     "write use-memory fast @string",0,NULL,1,1,1,0,0,0},
{"setex",setexCommand,4,"write use-memory @string",0,NULL,1,1,1,0,0,0},
{"append",appendCommand,3,"write use-memory fast @string",0,NULL,1,1,1,0,0,0},
{"strlen",strlenCommand,2,"read-only fast @string",0,NULL,1,1,1,0,0,0},
{"del",delCommand,-2,"write @keyspace",0,NULL,1,-1,1,0,0,0},
{"unlink",unlinkCommand,-2,"write fast @keyspace",0,NULL,1,-1,1,0,0,0},
{"exists",existsCommand,-2,"read-only fast @keyspace",0,NULL,1,-1,1,0,0,0},
{"mget",mgetCommand,-2,"read-only fast @string",0,NULL,1,-1,1,0,0,0},
// ....
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

而Sentinel则使用sentinel.c/sentinelcmds作为服务器的命令表,并且其中的INFO命令会使用Sentinel模式下的专用实现sentinel.c/sentinelInfoCommand函数,而不是普通Redis服务器使用的
实现redis.c/infoCommand函数:

struct redisCommand sentinelcmds[] = {
    {"ping",pingCommand,1,"fast @connection",0,NULL,0,0,0,0,0},
    {"sentinel",sentinelCommand,-2,"admin",0,NULL,0,0,0,0,0},
    {"subscribe",subscribeCommand,-2,"pub-sub",0,NULL,0,0,0,0,0},
    {"unsubscribe",unsubscribeCommand,-1,"pub-sub",0,NULL,0,0,0,0,0},
    {"psubscribe",psubscribeCommand,-2,"pub-sub",0,NULL,0,0,0,0,0},
    {"punsubscribe",punsubscribeCommand,-1,"pub-sub",0,NULL,0,0,0,0,0},
    {"publish",sentinelPublishCommand,3,"pub-sub fast",0,NULL,0,0,0,0,0},
    {"info",sentinelInfoCommand,-1,"random @dangerous",0,NULL,0,0,0,0,0},
    {"role",sentinelRoleCommand,1,"fast read-only @dangerous",0,NULL,0,0,0,0,0},
    {"client",clientCommand,-2,"admin random @connection",0,NULL,0,0,0,0,0},
    {"shutdown",shutdownCommand,-1,"admin",0,NULL,0,0,0,0,0},
    {"auth",authCommand,-2,"no-auth fast @connection",0,NULL,0,0,0,0,0},
    {"hello",helloCommand,-1,"no-auth fast @connection",0,NULL,0,0,0,0,0},
    {"acl",aclCommand,-2,"admin",0,NULL,0,0,0,0,0,0},
    {"command",commandCommand,-1, "random @connection", 0,NULL,0,0,0,0,0,0}
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

sentinel命令表也解释了为什么在Sentinel模式下Redis服务器不能执行诸如SET、DBSIZE、EVAL等等这些命令,因为服务器根本没有在命令表中载入这些命令。PING、SENTINEL、INFO、SUBSCRIBE、UNSUBSCRIBE、PSUBSCRIBE和PUNSUBSCRIBE这七个命令就是客户端可以对Sentinel执行的全部命令了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/388509
推荐阅读
相关标签
  

闽ICP备14008679号