Redis Sentinel 实现了 Redis 的高可用, 其基本原理包括: Sentinel 的 3 个定时监控任务, 主观下线和客观下线, Sentinel 领导者选举, 和故障转移.
3 个定时监控任务
1. 每隔 10s, 每个 Sentinel 节点会向主节点和从节点发送 info 命令获取最新的拓扑结构.
- $ redis-cli -p 6481 -a abcdefg monitor | egrep '127.0.0.1:51934.*INFO'
- 1532419769.058192 [0 127.0.0.1:51934] "INFO"
- 1532419779.081816 [0 127.0.0.1:51934] "INFO"
- 1532419789.089331 [0 127.0.0.1:51934] "INFO"
- 1532419799.118555 [0 127.0.0.1:51934] "INFO"
- $ netstat -atunlp | grep 51934
- tcp 0 0 127.0.0.1:51934 127.0.0.1:6481 ESTABLISHED 23418/redis-sentine
- tcp 0 0 127.0.0.1:6481 127.0.0.1:51934 ESTABLISHED 24055/redis-server
2. 每隔 2s, 每个 Sentinel 节点会向 Redis 数据节点的__sentinel__:hello 频道发送该 Sentinel 节点对于主节点的判断以及当前 Sentinel 节点的信息. 另外每个 Sentinel 节点会订阅一组事件频道 (如 + sdown 频道, 发布主观下线的消息), 共享 Sentinel 节点间的事件.
- $ redis-cli -p 6481 -a abcdefg monitor | egrep '127.0.0.1:51934.*PUBLISH'
- 1532420062.524075 [0 127.0.0.1:51934] "PUBLISH" "__sentinel__:hello" "127.0.0.1,26481,2e1df3bfaad006ad90295492eef2bc9b923abbf1,4,sfmaster,127.0.0.1,6481,4"
- 1532420064.531796 [0 127.0.0.1:51934] "PUBLISH" "__sentinel__:hello" "127.0.0.1,26481,2e1df3bfaad006ad90295492eef2bc9b923abbf1,4,sfmaster,127.0.0.1,6481,4"
- 1532420066.617168 [0 127.0.0.1:51934] "PUBLISH" "__sentinel__:hello" "127.0.0.1,26481,2e1df3bfaad006ad90295492eef2bc9b923abbf1,4,sfmaster,127.0.0.1,6481,4"
- 1532420068.667024 [0 127.0.0.1:51934] "PUBLISH" "__sentinel__:hello" "127.0.0.1,26481,2e1df3bfaad006ad90295492eef2bc9b923abbf1,4,sfmaster,127.0.0.1,6481,4"
$ redis-cli -p 26479 -a abcdefg subscribe +sdown
- ...
- 1) "message"
- 2) "+sdown"
- 3) "master sfmaster 127.0.0.1 6480"
$ redis-cli -p 26480 -a abcdefg subscribe +odown
- ...
- 1) "message"
- 2) "+odown"
- 3) "master sfmaster 127.0.0.1 6480 #quorum 2/2"
3. 每隔 1s, 每个 Sentinel 节点会向主节点, 从节点, 其余 Sentinel 节点发送一条 ping 命令做心跳检测, 确认这些节点是否可达.
- $ redis-cli -p 6481 -a abcdefg monitor | egrep '127.0.0.1:39042.*PING'
- 1532421426.017054 [0 127.0.0.1:39042] "PING"
- 1532421427.034552 [0 127.0.0.1:39042] "PING"
- 1532421428.049429 [0 127.0.0.1:39042] "PING"
- 1532421429.079257 [0 127.0.0.1:39042] "PING"
主观下线和客观下线
1. 主观下线
每个 Sentinel 节点间隔 1s 对主节点, 从节点, 其它 Sentinel 节点发送 ping 命令做心跳检测, 当这些节点超过 down-after-milliseconds 没进行有效回复时, Sentinel 节点就会对该节点做不可达判定, 该行为叫主观下线.
2. 客观下线
当 Sentinel 主观下线的节点是主节点时, 该 Sentinel 节点会通过 sentinel is-master-down-by-addr 命令, 向其它 Sentinel 节点询问对主节点的判断, 当超过 < quorum > 个 Sentinel 节点认为主节点有问题时, 该 Sentinel 节点会做客观下线决定.
从主观下线到客观下线的过程, Redis 没有使用什么一致性算法, 仅依据 gossip 协议在有效时间范围内收到其它 Sentinel 节点的确认即可.
领导者 Sentinel 节点选举
某 Sentinel 节点对主节点做客观下线后, 需要选举出领导者进行故障转移工作, Redis 使用了 Raft 算法实现领导者选举, 大致思路如下.
1. 每个 Sentinel 节点都有资格成为领导者, 当它对主节点做客观下线后, 会向其它 Sentinel 节点发送 sentinel is-master-down-by-addr, 要求把自己选举为领导者.
2. 收到命令的 Sentinel 节点, 如果没有同意过其它 Sentinel 节点的 sentinel is-master-down-by-addr 命令, 将同意该请求, 否则拒绝.
3. 如果该 Sentinel 节点发现自己的票数大于等于 max(quorum,num(sentinels/2)+1) 了, 那么它将成为领导者.
4. 若此过程没有选举出领导者, 将进入下一轮选举.
故障转移
选举出的领导者 Sentinel 节点负责故障转移, 具体步骤如下.
1. 在从节点中找出一个合适节点作为新的主节点.
2. 领导者 Sentinel 节点会对选出来的从节点执行 slaveof no one 命令, 让其成为主节点.
3. 领导者 Sentinel 节点会向剩余的从节点发送命令, 让它们成为新主节点的从节点, 复制规则和参数 parallel-syncs 有关.
4. Sentinel 节点集合会将原来的主节点在配置文件中更新为从节点, 当其恢复后命令它去复制新的主节点.
来源: http://www.bubuko.com/infodetail-2698725.html