Redis设计与实现(十五)Sentinel
就是Redis中的哨兵,哨兵这种思想是真的很伟大,我是很喜欢这玩意的。目前在java的开发中,一个分治,哨兵,桥接。这三个我是使用最多也是最经常使用的手段。
一个有意思的想法就是,redis主服务器可不可以是其他服务器的子服务器。当然是可以的。链式结构的思想实现。
Sentinel系统的主要作用就是当一个主服务器挂掉的时候,下面的小弟可以做主服务器,重新维持住体系。有点营长变团长的味道。
那么问题来了,如果是你设计这个Sentinel你觉得需要什么样的功能呢?在没看这本书之前,我是这样设计的
首先肯定是需要对子服务器,主服务器都进行心跳检测,来确定是否健康。
然后是对配置的考虑,如果主服务器的配置强于从服务器,那么主服务器肯定不是人人都能当的。也就是如果主服务器挂了之后,对于从服务器的权重的考虑,健康度+配置权重。
那么如何将主服务器降级为从服务器,从服务器如果升级为主服务器呢?升级好弄,其余的从服务器重新发个SLAVEOF命令就可以,主服务器也发这个命令就可以实现降级,但是主服务器和从服务器之间会存在一个循环依赖。看来Sentinel是怎么做的。
当主服务器的下线时间超过用户设定的时间的时候,会进行故障转移操作(主降从升)
并没有详细的操作过程,但是后续应该会有。
Sentinel也是一个特殊的Redis服务器。所以启动Sentinel也需要一定的步骤。
1.初始化服务器
Sentinel是不需要载入RDB or AOF来初始化数据库的,它的数据仅仅依赖于单次执行时候的数据。另外Sentinel的指令和Redis正常服务器的不相同。Sentinel是一个服务器,但是它主要是用来和服务器之间进行沟通的。所以对客户端的命令会相对比较少。
2.将普通Redis代码转化为Sentinel代码。如端口号,命令表
3.初始化Sentinel状态
服务器在配置玩Sentinel专属代码之后,会在sentinel.c/sentinelState结构中进行初始化。初始化的内容包括:主服务器的名字,主服务器的指针,脚本数量,时间等信息
4.初始化Sentinel状态中的master属性
master是一个字典,这个字典的键是被监视的服务器的名字,值是sentinelRedisInstance结构,代表了每一个被监视的服务器实例。
在初始化这个master字典的时候是根据配置文件进行载入的。
5.创建连向主服务器的网络连接
这一步也是初始化sentinel里面的步骤,被每个被监视的主服务器,sentinel会发送两个连接。一个是命令连接,用来专门向主服务器发送命令,并接受回复命令。另一个是订阅命令,用了专门连接主服务器的_sentinel_hello频道
当Sentinel服务器初始化完成之后,会每10s向已经连接的被监视的服务器发送INFO命令,主服务器会返回自身的信息,以及它下面的从服务器的信息。
Sentinel也会去主动连接从服务器
也是发送INFO命令,从服务器会回复,从服务器运行的ID,从服务器的角色,它的主服务器的地址已经端口,主从服务器之间的连接状态,优先级以及偏移量。简单的说就是通信是双方的,如果主地方得到的从信息和从地方得到的信息不符合,那么网络连接自然会存在一定问题。
然后Sentinel向主从服务器发送信息,默认的频率是两秒一次,sentinel使用另外一个频道用来接收返回的消息
Redis也支持多个sentinel监视一个主服务器的情况
主观下线判断相对简单一点,Sentinel对下面的被监视的服务器发送Ping命令,如果超过一定时间没有回复,那么就当作已经下线。
客观下线:是指sentinel向别的sentinel服务器询问,当其余的服务器大多数认为此服务器下线的时候就会认为它已经下线。