Redis哨兵(Sentinel)模式快速入门

更多内容,欢迎关注微信公众号:全菜工程师小辉。公众号回复关键词,领取免费学习资料。redis

当主服务器宕机后,须要手动把一台从服务器切换为主服务器,这就须要人工干预,费事费力,还会形成一段时间内服务不可用。 因此更多时候,咱们优先考虑哨兵(sentinel) 模式。算法

Redis sentinel是Redis高可用实现方案:故障发现、故障自动转移、配置中心、客户端通知。从Redis的2.6版本开始提供的,可是当时这个版本的模式是不稳定的,直到Redis的2.8版本之后,这个哨兵模式才稳定下来,在生产环境中,若是想要使用Redis的哨兵模式,也会尽可能使用Redis的2.8版本以后的版本。api

哨兵虽然有一个单独的可执行文件Redis-sentinel ,但实际上它只是一个运行在特殊模式下的 Redis服务器,你能够在启动一个普通Redis服务器时经过给定--sentinel选项来启动哨兵,哨兵的一些设计思路和zookeeper很是相似。服务器

Redis哨兵模式

sentinel的定时任务

sentinel机制中有三种重要的定时任务。微信

  1. 每10秒每一个sentinel对master和slave执行info

做用:网络

  • 发现slave节点。
  • 确认主从关系。
  1. 每2秒每一个sentinel经过master节点的channel交换信息(pub/sub)

做用:学习

  • 互相通讯掌握节点的信息和自身信息,能够感知新加入的sentinel

> 经过master节点的__sentinel__:hello频道进行交互,全部sentinel订阅这个频道并每2秒向该频道发布信息设计

  1. 每1秒每一个sentinel对其余sentinel和master,slave进行ping

做用:代理

  • 心跳检测

主观下线和客观下线

主观下线

主观下线:单个sentinel节点对Redis节点通讯失败的“偏见”。code

这是一种主观下线。由于在复杂的网络环境下,这个sentinel与这个master不通,可是若是master与其余的sentinel都是通的呢?因此是一种“偏见”。

这是依靠的第三种定时:每秒去ping一下周围的sentinel和Redis。对于slave Redis,可使用这个主观下线,由于他不须要进行故障转移;可是对于master Redis,必须使用客观下线。

客观下线

客观下线:全部sentinel节点对master Redis节点失败“达成共识”(超过quorum个则统一,quorum可配置)。

这是依靠的第二种定时:每两秒,sentinel之间进行“商量”(一个 sentinel 能够经过向另外一个 sentinel 发送 SENTINEL is-master-down-by-addr 命令来询问对方是否定为给定的服务器已下线。)

对于master redis的下线,必需要达成共识才能够,由于涉及故障转移,仅仅依靠一个sentinel判断是不够的

领导者选举

当sentinel集群须要故障转移的时候会在集群中选出Leader执行故障转移操做。sentinel采用了Raft协议实现了sentinel间选举Leader的算法,不过也不彻底跟论文描述的步骤一致。sentinel集群运行过程当中故障转移完成,全部sentinel又会恢复平等。Leader仅仅是故障转移操做出现的角色。

选举流程

  1. 某个sentinel认定master客观下线的节点后,该sentinel会先看看本身有没有投过票,若是本身已经投过票给其余sentinel了,在2倍故障转移的超时时间本身就不会成为Leader。至关于它是一个Follower。
  2. 若是该sentinel还没投过票,那么它就成为Candidate。
  3. 和Raft协议描述的同样,成为Candidate,sentinel须要完成几件事情
    3.1 更新故障转移状态为start
    3.2 当前epoch加1,至关于进入一个新term,在sentinel中epoch就是Raft协议中的term。
    3.3 更新本身的超时时间为当前时间随机加上一段时间,随机时间为1s内的随机毫秒数。 3.4 向其余节点发送is-master-down-by-addr命令请求投票。命令会带上本身的epoch。 3.5 给本身投一票,在sentinel中,投票的方式是把本身master结构体里的leader和leader_epoch改为投给的sentinel和它的epoch。
  4. 其余sentinel会收到Candidate的is-master-down-by-addr命令。若是sentinel当前epoch和Candidate传给他的epoch同样,说明他已经把本身master结构体里的leader和leader_epoch改为其余Candidate,至关于把票投给了其余Candidate。投过票给别的sentinel后,在当前epoch内本身就只能成为Follower。
  5. Candidate会不断的统计本身的票数,直到他发现认同他成为Leader的票数超过一半并且超过它配置的quorum(quorum能够参考《redis sentinel设计与实现》)。sentinel比Raft协议增长了quorum,这样一个sentinel可否当选Leader还取决于它配置的quorum。
  6. 若是在一个选举时间内,Candidate没有得到超过一半且超过它配置的quorum的票数,本身的此次选举就失败了。
  7. 若是在一个epoch内,没有一个Candidate得到更多的票数。那么等待超过2倍故障转移的超时时间后,Candidate增长epoch从新投票。
  8. 若是某个Candidate得到超过一半且超过它配置的quorum的票数,那么它就成为了Leader。
  9. 与Raft协议不一样,Leader并不会把本身成为Leader的消息发给其余sentinel。其余sentinel等待Leader从slave选出master后,检测到新的master正常工做后,就会去掉客观下线的标识,从而不须要进入故障转移流程。

故障转移过程

  1. 当多个sentinel发现并确认了master有问题
  2. 接着会选举出一个sentinel做为领导
  3. 再选举出一个slave做为master
  4. 通知其他的slave,新的master是谁
  5. 通知客户端一个主从的变化
  6. 最后,sentinel会等待旧的master复活,而后将新master成为slave

那么,如何选择“合适”的slave节点呢?

  1. 选择slave-priority(slave节点优先级,人为配置)最高的slave节点,若是存在则返回,不存在则继续。
  2. 其次会选择复制偏移量最大的slave节点(复制得最完整),若是存在则返回,不存在则继续
  3. 最后会选择run_id最小的slave节点(启动最先的节点)

客户端实现高可用的基本原理

故障转移后客户端没法感知将没法保证正常的使用。因此,实现客户端高可用的步骤以下:

  1. 客户端获取sentinel节点集合

Redis哨兵模式

  1. 客户端经过sentinel get-master-addr-by-name master-name这个api来获取对应主节点信息

Redis哨兵模式

  1. 客户端验证当前获取的“主节点”是真正的主节点,这样的目的是为了防止故障转移期间主节点的变化

Redis哨兵模式

  1. 客户端保持和sentinel节点集合的联系,即订阅sentinel节点相关频道,时刻获取关于主节点的相关信息

Redis哨兵模式

从上面的模型能够看出,Redis sentinel客户端只有在初始化和切换主节点时须要和sentinel进行通讯来获取主节点信息,因此在设计客户端时须要将sentinel节点集合考虑成配置(相关节点信息和变化)发现服务。

须要说明的问题

  • 尽量在不一样物理机上和同一个网络部署Redis sentinel的全部节点
  • Redis sentinel中的sentinel节点个数应该大于等于3且最好是奇数。(节点数多能够保证高可用)
  • Redis sentinel中的数据节点和普通数据节点没有区别。每一个sentinel节点在本质上仍是一个Redis实例,只不过和Redis数据节点不一样的是,其主要做用是监控Redis数据节点
  • 客户端初始化时链接的是sentinel节点集合,再也不是具体的Redis节点,但sentinel只是配置中心不是代理。

更多内容,欢迎关注微信公众号:全菜工程师小辉。公众号回复关键词,领取免费学习资料。

哎呀,若是个人名片丢了。微信搜索“全菜工程师小辉”,依然能够找到我

相关文章
相关标签/搜索