这节介绍Redis的高可用解决方案:Sentinelhtml
Sentinel是Redis官方推荐的高可用(HA)解决方案,当用Redis作master-slave的高可用方案时,假如master宕机了,Redis自己(包括它的不少客户端)都没有实现自动进行主备切换。redis
Sentinel自己是一个运行在特殊模式下的Redis服务器,它能监控多个master-slave集群,发现master宕机后能进行自动切换。服务器
sentinel经过配置项中的网络
sentinel monitor <master name> <master ip> <master port> <quorum>
选项来获取master节点的信息。3d
在启动后sentinel会创建同master节点的命令链接和订阅链接。以便经过命令链接向主节点发送命令,经过订阅链接订阅服务器的 sentinel:hello 频道。code
sentinel每10秒会向master节点发送INFO命令,经过分析命令的返回结果可以知道主节点和从节点的信息。对于每一个从节点,sentinel也会向它创建一个命令链接和订阅链接。htm
sentinel每2秒经过命令链接向所监听的节点发送订阅命令,如blog
PUBLISH _sentinel_:hello …..
其中的信息包括了sentinel自己的信息以及本身记录的主节点信息。同时,sentinel也会订阅_sentinel_:hello频道,因此sentinel可以以这种方式同其余的sentinel节点通讯,以同步信息,见goosip协议。排序
当sentinel从订阅信息中发现一个新的sentinel节点时,会向该新发现的节点创建命令链接,最后监视同一主服务器的各个sentinel节点会造成互相链接的网络。ip
配置项
sentinel down-after-milliseconds <主节点名> <中断时间ms>
设置了sentinel主观下线的时间。sentinel每隔一秒就会向主节点发送PING命令,若是master在“中断时间”内不回应PONG 或者是回复了一个错误消息,那么这个sentinel会主观地(单方面地)认为这个master已经不可用了(SDOWN)。
当sentinel判断主节点已经处于主观下线状态后,会向其余sentinel发送
is-master-down-by-add
命令,以询问其余sentinel的状态,确认该主节点是否处于下线状态(主观下线或者客观下线)。当回复的下线状态的数量达到配置项中的quorum值时,则该sentinel会将主节点标记为客观下线状态(ODOWN)。
当sentinel判断主节点处于客观下线状态后,会触发故障转移。
发生故障转移时,会从监听主节点的sentinel中选举出主的sentinel来处理故障转移的过程。选举的过程相似于Raft协议,由标记客观下线的sentinel节点充当candidate,向其余sentinel节点(follower)发起投票,当某个candidate从follower得到的票数超过一半后,该候选者就会成为leader。而sentinel中的epoch,配置纪元相似于Raft中的term,每次选举后都会自增。主要过程为:
每一个充当candidate的sentinel节点都会要求其余sentinel节点发送is-master-down-addr
命令,将本身设置为leader。
收到命令的sentinel节点,若是当前epoch和candidate传给他的epoch同样,说明他已经把本身的票投给了其余candidate。投过票给别的sentinel后,在当前epoch内本身就只能成为follower。若是该节点还没投过票,会采起先到先得的规则,将本身的票投给请求的candidate节点。
收到回复的candidate节点,会检查响应的epoch值和leader_runid值是否同自身的值一致,是的话则表示得到了一票。
当某个candidate节点得到半数以上的票数时,该节点便成为了leader节点。
若是必定时间内无法选举出leader节点,则每一个candidate节点会等待随机时间后再次发起选举,知道选出leader节点为止。
选举出领头sentinel节点后,将由该节点处理故障转移,过程以下:
在已下线主节点的全部从节点中,选出一个从节点,将其转换为主节点。
主sentinel会按照下面的规则选择适合的slave节点上升为master节点:
去除已下线的slave节点
去除最近五秒内没有回复过主sentinel节点INFO信息的slave节点
去除与已下线主节点链接断开超过down-after-milliseconds*10毫秒的slave节点
根据各slave节点的优先级,从小到大排序,选择优先级最小的节点。对于相同优先级的节点,选择复制偏移量最大和runid最小的节点。
最后向被选择出来的slave节点发送SLAVE OF NO ONE
命令。
向已下线主节点下的全部从节点发送SLAVE OF命令,改成复制新的主节点。
将已下线主节点设置为新主节点的从节点。
其中,上面步骤1)中的slave节点优先级由redis配置文件中的slave-priority N
选项控制。0做为一个特殊的优先级,标识这个slave不能做为master,因此一个优先级为0的slave永远不会被 哨兵挑选提高为master。
上步骤2) 中,从节点须要同步新的主节点的信息,期间会致使从节点不可用,能够经过
sentinel parallel-syncs mymaster <n>
来控制同时进行同步的从节点的数量。这个数字越小,完成故障转移所需的时间就越长,可是若是这个数字越大,就意味着越多的slave由于复制而不可用。
Redis不保证强一致性,在发生网络故障时,有可能出现脑裂。从脑裂发生到网络恢复正常,复制结束的这段时间里,异常主节点写入的数据将丢失。为了不数据的丢失,能够对主节点增长以下配置:
min-slaves-to-write 1 #执行写操做所需的最少slave服务器数量,若是数量少于设定的值,写操做将被拒绝 min-slaves-max-lag 10 #网络延迟的最大时间,当写操做延迟大于所设定的时间,写操做将被拒绝
我的公众号:啊驼