sentinel是redis高可用的解决方案,sentinel系统(N个sentinel实例,N >= 1)能够监视一个或者多个redis master服务,以及这些master服务的全部从服务;当某个master服务下线时,自动将该master下的某个从服务升级为master服务替代已下线的master服务继续处理请求。redis
可使用命令数据库
redis-sentinel /path/to/sentinel.conf服务器
或者网络
redis-server /path/to/sentinel.conf --sentinel数据结构
来启动sentinel异步
sentinel启动时,须要通过一下几个步骤spa
sentinel本质上是一个特殊的redis服务,因此初始化的时候跟redis服务初始化差很少,不过有几点不同;首先sentinel不会载入RDB或者AOF文件,由于sentinel根本不使用数据库,其次,sentinel不能使用数据库键值对方面的命令,例如set、del、flushdb等等,同时,sentinel也不能使用事务、脚本、RDB或者AOF持久化命令,最后,复制命令,发布与订阅命令,文件事件处理器,时间事件处理器等只能在sentinel内部使用。server
将redis服务的代码转成sentinel的专用代码,例如sentinel的command与redis的command命令表就不同(redis不少命令,sentinel不须要)事件
主要是初始化sentinelState结构,sentinelState里面保存了sentinel的全部功能和状态,sentinelState结构以下事务
其实就是初始化sentinelState中的masters属性,masters字典中记录了全部被监视的主服务器信息,其中键是服务器名字,值是服务对应的sentinelRedisInstance结构,主要有实例名字,运行id,实例地址,客观下线票数,主管下线的最大无响应时间等等
sentinelState中masters字典的大体结构以下:
建立与被监视的master的网络链接后,sentinel成为该master的客户端,它会向master发送命令,并从master的响应中获取master的信息。对于每一个被监视的master,sentinel会向其建立两个异步的网络链接
命令链接,这个链接专门用于向master发送命令,并接收命令回复
订阅链接,专门订阅master服务的 sentinel:hello频道
sentinel以每10秒一次的频率向master发送info命令,经过info的回复来分析master信息,master的回复主要包含了两部分信息,一部分是master自身的信息,一部分是master全部的slave(从)的信息,因此sentinel能够自动发现master的从服务。sentinel从master哪儿获取到的master自身信息以及master全部的从信息,将会更新到sentinel的sentinelState中及masters(sentinelRedisInstance结构)中的slaves字典中
当sentinel发现master有新的从服务时,不但为从服务建立相信的实例结构,并且还会建立链接到该从服务的命令链接和订阅链接,建立命令链接后,sentinel会10秒每次的向从服务发送info命令,并从回复信息中提取从服务ID、从服务角色、从服务所属的主服务的ip及端口、主从服务的链接状态、从服务的优先级、从服务的复制偏移量等信息;建立或者更新到从服务的sentinelRedisInstance结构。
sentinel会以每两秒一次的频率向全部的被监视服务器(master和从服务)发送询问命令,命令格式以下
publish ___sentinel___:hello s_ip s_port s_runid s_epoch m_name m_ip m_port m_epoch
各个参数的解析以下
s_ip:sentinel的ip
s_port:sentinel的端口
s_runid:sentinel云心id
s_epoch:sentinel当前的配置纪元
m_name:主服务器名字
m_ip:主服务器ip
m_port:主服务器端口
m_epoch:主服务器纪元
sentinel与被监视的服务之间,一方面,sentinel经过命令连接发送信息到频道,另外一方面,经过订阅链接从频道中接收信息。
对于同一服务的多个sentinel,一个sentinel发送的信息,会被其余sentinel收到,用于更新对该sentinel以及被监视服务的认知,用于更新sentinelRedisInstance的sentinels字典信息(请看sentinelRedisInstance的数据结构)及master信息。
当sentinel经过频道发现新的sentinel时,不但会更新上图的sentinel字典,同时会与新的sentinel创建命令链接(不会创建订阅链接,没啥可订阅的,由于sentinel与master及从创建订阅链接,是用来发现新的sentinel,而sentinel之间是已知的,因此不须要订阅链接),最终,监视同一个服务的多个sentinel会互联造成一个网络。
首先解析一下什么叫主观下线,所谓主观下线,就是单个sentinel认为某个服务下线(有多是接收不到订阅,之间的网络不通等等缘由)。
sentinel会以每秒一次的频率向全部与其创建了命令链接的实例(master,从服务,其余sentinel)发ping命令,经过判断ping回复是有效回复,仍是无效回复来判断实例时候在线(对该sentinel来讲是“主观在线”)。
sentinel配置文件中的down-after-milliseconds设置了判断主观下线的时间长度,若是实例在down-after-milliseconds毫秒内,返回的都是无效回复,那么sentinel回认为该实例已(主观)下线,修改其flags状态为SRI_S_DOWN。若是多个sentinel监视一个服务,有可能存在多个sentinel的down-after-milliseconds配置不一样,这个在实际生产中要注意。
当sentinel监视的某个服务主观下线后,sentinel会询问其它监视该服务的sentinel,看它们是否也认为该服务主观下线,接收到足够数量(这个值能够配置)的sentinel判断为主观下线,既任务该服务客观下线,并对其作故障转移操做。
sentinel经过发送 SENTINEL is-master-down-by-addr ip port current_epoch runid,(ip:主观下线的服务id,port:主观下线的服务端口,current_epoch:sentinel的纪元,runid:*表示检测服务下线状态,若是是sentinel 运行id,表示用来选举领头sentinel)来询问其它sentinel是否赞成服务下线。
一个sentinel接收另外一个sentinel发来的is-master-down-by-addr后,提取参数,根据ip和端口,检测该服务时候在该sentinel主观下线,而且回复is-master-down-by-addr,回复包含三个参数:down_state(1表示已下线,0表示未下线),leader_runid(领头sentinal id),leader_epoch(领头sentinel纪元)。
sentinel接收到回复后,根据配置设置的下线最小数量,达到这个值,既认为该服务客观下线
一个redis服务被判断为客观下线时,多个监视该服务的sentinel协商,选举一个领头sentinel,对该redis服务进行古战转移操做。选举领头sentinel遵循如下规则:
全部的sentinel都有公平被选举成领头的资格
全部的sentinel都有且只有一次将某个sentinel选举成领头的机会(在一轮选举中),一旦选举某个sentinel为领头,不能更改
sentinel设置领头sentinel是先到先得,一旦当前sentinel设置了领头sentinel,之后要求设置sentinel为领头请求都会被拒绝
每一个发现服务客观下线的sentinel,都会要求其余sentinel将本身设置成领头
当一个sentinel(源sentinel)向另外一个sentinel(目sentinel)发送is-master-down-by-addr ip port current_epoch runid命令的时候,runid参数不是*,而是sentinel运行id,就表示源sentinel要求目标sentinel选举其为领头
源sentinel会检查目标sentinel对其要求设置成领头的回复,若是回复的leader_runid和leader_epoch为源sentinel,表示目标sentinel赞成将源sentinel设置成领头
若是某个sentinel被半数以上的sentinel设置成领头,那么该sentinel既为领头
若是在限定时间内,没有选举出领头sentinel,暂定一段时间,再选举
故障转移分为三个主要步骤
sentinel状态数据结构中保存了主服务的全部从服务信息,领头sentinel按照以下的规则从从服务列表中挑选出新的主服务
删除列表中处于下线状态的从服务
删除最近5秒没有回复过领头sentinel info信息的从服务
删除与已下线的主服务断开链接时间超过 down-after-milliseconds*10毫秒的从服务,这样就能保留从的数据比较新(没有过早的与主断开链接)
领头sentinel从剩下的从列表中选择优先级高的,若是优先级同样,选择偏移量最大的(偏移量大说明复制的数据比较新),若是偏移量同样,选择运行id最小的从服务
挑选出新的主服务以后,领头sentinel 向原主服务的从服务发送 slaveof 新主服务 的命令,复制新master
同理,当已下线的服务从新上线时,sentinel会向其发送slaveof命令,让其成为新主的从