为什么要用sentinel
主从复制的问题
主从复制是Redis高可用的基础,可以在主节点挂掉之后,将从节点顶上去成为新的主节点,同时从节点还可以缓解主节点读的压力。但是主从复制最明显的缺陷就是,当主节点挂了之后,需要人工去将从节点晋升为主节点,并且需要修改客户端的主节点地址以及命令所有从节点去复制新的主节点的数据。
sentinel的功能
Redis Sentinel为Redis提供高可用性,可以实现自动化的故障转移并通知应用方,从节点晋升为主节点的整个过程不需要人工干预。 根据官网介绍,redis sentinel提供了以下功能:
- 监控(Monitoring):Sentinel会不断的检查你的主节点和从节点是否正常工作。
- 通知(Notification):被监控的Redis实例如果出现问题,Sentinel可以通过API(pub)通知系统管理员或者其他程序。
- 自动故障转移(Automatic failover):如果一个master离线,Sentinel会开始进行故障转移,master下的一个slave会被选为新的master,其他的slave会开始复制新的master。应用可以通过Redis服务的通知机制更新新的master地址。
- 配置提供者(Configuration provider):客户端可以把Sentinel作为权威的配置发布者来获得最新的master地址。如果发生了故障转移,Sentinel集群会通知客户端新的master地址,并刷新redis的配置。
sentinel的原理
为了实现高可用,sentinel一般都是由集群组成,类似zookeeper,最少都是3个节点组成。与zookeeper不同的是,sentinel采用的分布式一致性协议是raft协议。 sentinel节点是特殊的redis节点,只是它不存储数据,而且只支持部分命令。
三个定时监控任务
sentinel通过三个定时监控任务实现对各个节点的发现和监控。
- 每隔10秒,每个sentinel节点都会向主节点和从节点发送info命令获取对应节点的信息(对主节点执行info replication命令可以获取从节点的信息,所以sentinel中只需要配置主节点信息就可以获取所有从节点信息)。
- 每隔2秒,每个sentinel节点会向Redis数据节点的_sentinel_:hello频道上发送该节点对于主节点状态的判断以及自己的信息。sentinel连接redis实例时,会创建两个连接,一个是commands命令连接和一个pub/sub发布订阅连接。每个sentinel也会订阅_sentinel_:hello这个频道,用于接收其它sentinel发布的消息以了解其它sentinel节点对于主节点状态的判断(为主节点客观下线做依据)以及其它sentinel节点的信息(用于发现新的sentinel节点)。
- 每隔1秒,每个sentinel节点会向主节点、从节点、其它sentinel节点发送一个ping命令做心跳检测,来确认这些节点是否可达。
主观下线和客观下线
主观下线(sdown)
上面定时任务的第三个,每隔1秒向其它所有节点发送一个ping命令。如果节点超过down-after-milliseconds * 10的时间。(默认是30秒)都没有进行有效回复(+PONG、-LOADING 或者 -MASTERDOWN这三种都是有效回复),sentinel节点就会对该节点做失败判定,这种行为就叫做主观下线。
客观下线(odown)
当sentinel主观下线的节点是主节点时,该sentinel节点就会向其它sentinel节点发送sentinel is-master-down-by-addr(这个命令还可以用于sentinel的leader选举) 命令询问他们对主节点的判断,当大于等于quorum(这个在sentinel的配置文件中配置的,如果sentinel节点是3个,quorum就配置为2。)个的sentinel都认为主节点已经挂了,那么该sentinel节点就会对主节点进行客观下线。(所以客观下线就是大部分的sentinel都认为主节点挂了)
sentinel的leader选举
当sentinel对主节点做客观下线之后,还不能开始故障转移。因为故障转移的工作只需要一个sentinel就可以完成,所以sentinel节点间会选举一个leader来完成这个工作。Redis采用了Raft算法实现leader选举,不过redis的实现与论文描述不完全一致(因为sentinel只有在进行故障转移的时候才需要leader,其它时间不需要leader)。
- 某个Sentinel认定master客观下线的节点后,该Sentinel会先看看自己有没有投过票,如果自己已经投过票给其他Sentinel了,在2倍故障转移的超时时间自己就不会成为Leader。相当于它是一个Follower。
- 如果该Sentinel还没投过票,那么它就成为Candidate。
- 成为Candidate之后,Sentinel需要完成几件事情
- 更新故障转移状态为start
- 当前epoch加1,相当于进入一个新term,在Sentinel中epoch就是Raft协议中的term。
- 更新自己的超时时间为当前时间随机加上一段时间,随机时间为1s内的随机毫秒数。
- 向其他节点发送is-master-down-by-addr命令请求投票。命令会带上自己的epoch。
- 给自己投一票,在Sentinel中,投票的方式是把自己master结构体里的leader和leader_epoch改成投给的Sentinel和它的epoch。
- 其他Sentinel会收到Candidate的 is-master-down-by-addr 命令。如果Sentinel当前epoch和Candidate传给他的epoch一样,说明他以及把票投给了这个Candidate。投过票给别的Sentinel后,在当前epoch内自己就只能成为Follower。
- Candidate会不断的统计自己的票数,直到他发现认同他成为Leader的票数超过一半而且大于等于quorum。Sentinel比Raft协议增加了quorum,这样一个Sentinel能否当选Leader还取决于它配置的quorum。
- 如果在一个选举时间内,Candidate没有获得超过一半且大于等于quorum的票数,自己的这次选举就失败了。
- 如果在一个epoch内,没有一个Candidate获得足够的票数。那么只能等待超过2倍故障转移的超时时间(故障转移的超时时间默认是3分钟,所以这里是6分钟)后,Candidate增加epoch重新投票。
- 如果某个Candidate获得超过一半且大于等于quorum的票数,那么它就成为了Leader。
- 与Raft协议不同,Leader并不会把自己成为Leader的消息发给其他Sentinel。其他Sentinel等待Leader从slave选出master后,检测到新的master正常工作后,就会去掉旧的master客观下线的标识,从而不需要进入故障转移流程。
在sentinel中,谁先完成主观下线,就会获得主动权(最先发送命令获取其它sentinel对master的判断,然后最先完成客观下线)。当sentinel完成客观下线后,就会马上再次发送命令向其它sentinel索要投票,由于每个sentinel只能投一票,最开始索要的sentinel可以得到2票,其它sentinel最多还有1票,所以最后的leader一般就是最开始索要投票的那个sentinel。
故障转移
选举出的Leader负责接下来的故障转移工作。就是从从节点中选出一个作为新的主节点。
- 选择出一个可用的slave节点。
- 过滤掉不健康(主观下线或掉线),5秒内没有有效回复过sentinel节点ping,与主节点失联超过down-after-milliseconds * 10的时间。
- 选择从节点优先级最高的salve作为新的master。
- 如果优先级相同,比较slave对原master的复制偏移量,偏移量大的slave被选为新master。
- 如果复制偏移量相同,那就直接比较slave的runid,字符串小的slave被选为新master。
- 将选出来的节点执行slaveof no one命令,让其成为新的master。
- 向剩余的从节点发送命令,让他们成为新的master的从节点,然后去复制master的数据。Sentinel有个parallel_syncs参数,用来确定一次让多少个slave复制新master。由于初次复制会采用快照同步,此时slave会处于不可用状态,所以一般设置一次让一个salve进行复制,虽然这样可能花费的时间长一点,但每次只会有一个slave处于不可用状态。
- 全部故障转移工作完成后,leader Sentinel就会推送+switch-master消息,同时重置master,重置操作会释放掉原来master全部的slave对象和监听该master的其他Sentinel对象,然后创建出新的slave对象。
简单搭建Redis Sentinel
Redis-server主从复制搭建
先把Redis.conf复制三份到工作目录。然后修改主节点和从节点的配置。
主节点:master.conf
# 后台启动
daemonize yes
# 日志文件对应的位置(日志文件需要自己另行创建,位置可以自己改)
logfile /var/log/redis/master.log
# 端口号
port 6379
# 主节点的密码
# 这里为什么也要配置呢,因为发生故障转移后,当前主节点就会变成从节点
# sentinel只会自动重写主从关系,并不会重写masterauth
masterauth 123456
# 当前结点的密码
requirepass 123456
从节点1: slave1.conf
# 后台启动
daemonize yes
# 日志文件对应的位置
logfile /var/log/redis/slave1.log
# 端口号
port 6378
# 主节点的密码
masterauth 123456
# 当前结点的密码
requirepass 123456
# 指定主节点的地址和端口
slaveof 127.0.0.1 6379
从节点2: slave2.conf
# 后台启动
daemonize yes
# 日志文件对应的位置
logfile /var/log/redis/slave2.log
# 端口号
port 6377
# 主节点的密码
masterauth 123456
# 当前结点的密码
requirepass 123456
# 指定主节点的地址和端口
slaveof 127.0.0.1 6379
分别启动三个节点:
sudo redis-server master.conf
sudo redis-server slave1.conf
sudo redis-server slave2.conf
查看master节点的启动日志,以下是部分日志内容。
Replica 127.0.0.1:6378 asks for synchronization
Starting BGSAVE for SYNC with target: disk
9467:M 01 Feb 2020 16:45:29.290 * Background saving started by pid 9510
9510:C 01 Feb 2020 16:45:29.379 * DB saved on disk
9467:M 01 Feb 2020 16:45:29.526 * Background saving terminated with success
9467:M 01 Feb 2020 16:45:29.527 * Synchronization with replica 127.0.0.1:6378 succeeded
从日志可知,从节点先向主节点发送了一个同步请求,然后master节点开启了一个后台进程进行BGSAVE将当前内存的数据全部快照到磁盘文件中,然后再将快照文件的内容全部传送到从节点。
Sentinel配置启动
先把redis-sentinel.conf复制三份到工作目录,分别修改三个节点的以下配置:
节点1: sentinel1.conf
# 端口,也是默认端口
port 26379
# 后台启动
daemonize yes
# sentinel监控Redis主节点的配置
# 对应的命令:sentinel monitor <master-name> <ip> <redis-port> <quorum>
# master-name 指的是主节点的名字,可以自己定义
# ip 指的是主节点的ip地址
# redis-port 指的是主节点的端口
# quorum 这个值既用于主节点的客观下线,又用于sentinel的leader选举,具体可见上面的原理
sentinel monitor mymaster 127.0.0.1 6379 2
# 主节点响应sentinel的最大时间间隔,超过这个时间,sentinel认为主节点下线,默认30秒
sentinel down-after-milliseconds mymaster 3000
# 进行故障转移时,设置最多有多少个slave同时复制新的master
# 由于slave在复制时,会处于不可用的状态(要先清空数据,然后再加载主节点的数据)
# 所以设置一次允许一个slave去复制master
sentinel parallel-syncs master 1
# 故障转移的超时时间,默认3分钟。
# 当前sentinel对一个master节点进行故障转移后,需要等待这个时间后才能
# 再次对这个master节点进行故障转移(此时其它sentinel依然可以对该master进行故障转移)
# 进行故障转移时,配置所有slave复制master的最大时间,如果超时了,就不会按照parallel-syncs规则进行了
# sentinel进行leader选举时,如果没有选出leader,需要等到2倍这个时间才能进行下一次选举
sentinel failover-timeout master 180000
# 主节点如果设置了密码,就在这里配置
sentinel auth-pass mymaster 123456
# log文件的位置
logfile /var/log/redis/sentinel1.log
另外两个节点改一下端口就ok啦,我这里设置的是26378和26377。
启动三个sentinel节点,因为sentinel也是redis节点,所以也使用redis-server命令启动,只不过是用sentinel模式启动。
sudo redis-server sentinel1.conf --sentinel
sudo redis-server sentinel2.conf --sentinel
sudo redis-server sentinel3.conf --sentinel
来看一下sentinel的启动日志:
9791:X 01 Feb 2020 17:10:52.503 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
9791:X 01 Feb 2020 17:10:52.504 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=9791, just started
9791:X 01 Feb 2020 17:10:52.504 # Configuration loaded
9792:X 01 Feb 2020 17:10:52.523 * Increased maximum number of open files to 10032 (it was originally set to 1024).
9792:X 01 Feb 2020 17:10:52.528 * Running mode=sentinel, port=26379.
9792:X 01 Feb 2020 17:10:52.644 # Sentinel ID is 3b9f4dfc0dcf08b0d21478cf58d0227e1ba61564
9792:X 01 Feb 2020 17:10:52.645 # +monitor master mymaster 127.0.0.1 6379 quorum 2
9792:X 01 Feb 2020 17:10:52.647 * +slave slave 127.0.0.1:6377 127.0.0.1 6377 @ mymaster 127.0.0.1 6379
9792:X 01 Feb 2020 17:10:52.675 * +slave slave 127.0.0.1:6378 127.0.0.1 6378 @ mymaster 127.0.0.1 6379
9792:X 01 Feb 2020 17:11:18.371 * +sentinel sentinel 0bf2c2c19fcb5e0a77a79485ea7f2d8d012a03d8 127.0.0.1 26378 @ mymaster 127.0.0.1 6379
9792:X 01 Feb 2020 17:11:24.982 * +sentinel sentinel 7ea991444528f91b83fb86534dcb7db28e862507 127.0.0.1 26377 @ mymaster 127.0.0.1 6379
可以看到Redis是在sentinel模式下启动的,并且没有加载数据的过程(sentinel不需要数据)。然后会给sentinel分配一个ID,在sentinel集群中就是通过这个ID来识别sentinel的。
然后sentinel执行了监控主节点的命令(在配置文件中配置的),通过主节点获取到了两个从节点的信息。然后其它两个sentinel也启动了并加入了集群中。
在sentinel集群启动之后,会自动刷新配置,将主节点的两个从节点信息和其它的sentinel节点的信息写入配置中。
# Generated by CONFIG REWRITE
# sentinel的工作目录
dir "/home/monk-jay/redis/sentinel"
# 保护模式关闭
protected-mode no
# sentinel监控的master节点对应的领导纪元
# 这个就是用于领导选举时投票用的,记录的是当前投票的leader的纪元
# 这个值和当前纪元相同,说明当前节点已经投过票了
sentinel leader-epoch mymaster 5
# master下的两个slave节点信息
sentinel known-replica mymaster 127.0.0.1 6378
sentinel known-replica mymaster 127.0.0.1 6377
# 另外两个sentinel的信息
sentinel known-sentinel mymaster 127.0.0.1 26377 7ea991444528f91b83fb86534dcb7db28e862507
sentinel known-sentinel mymaster 127.0.0.1 26378 0bf2c2c19fcb5e0a77a79485ea7f2d8d012a03d8
# 当前纪元
sentinel current-epoch 5
sentinel客户端使用
进入客户端的方式与Redis一样,也是使用redis-cli。由于有多个redis实例,所以需要指定端口。
sudo redis-cli -p 26379
- 查看当前sentinel的信息。
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1 # 监控master的数量
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
# 监控的master的信息
master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3
- 查看监控的所有master的信息
127.0.0.1:26379> sentinel masters
1) 1) "name"
2) "mymaster"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6379"
7) "runid"
8) "b16c053f53588d72b655e4d91d2d280a591bc5ff"
9) "flags"
10) "master"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "960"
19) "last-ping-reply"
20) "960"
21) "down-after-milliseconds"
22) "30000"
23) "info-refresh"
24) "4073"
25) "role-reported"
26) "master"
27) "role-reported-time"
28) "58473813"
29) "config-epoch"
30) "5"
31) "num-slaves"
32) "2"
33) "num-other-sentinels"
34) "2"
35) "quorum"
36) "2"
37) "failover-timeout"
38) "180000"
39) "parallel-syncs"
40) "1"
- 查看指定master节点的信息,因为这里只监控了一个master节点,所以显示和上面一样
sentinel master <master_name>
- 显示指定 主节点 的所有 从节点 以及它们的状态。
sentinel slaves <master_name>
- 查看指定的master的地址和端口
127.0.0.1:26379> sentinel get-master-addr-by-name mymaster
1) "127.0.0.1"
2) "6379"
故障转移
模拟宕机
sentinel有个命令:强制当前sentinel执行故障转移(不会跟其他sentinel商量),当故障转移完成后,其它sentinel节点会按照故障转移的结果进行自身配置的更新。该命令可以模拟master宕机,然后进行故障转换。
127.0.0.1:26379> sentinel failover mymaster
OK
然后来看一下当前sentinel的日志。
9792:X 02 Feb 2020 11:19:23.353 # Executing user requested FAILOVER of 'mymaster'
9792:X 02 Feb 2020 11:19:23.353 # +new-epoch 6
9792:X 02 Feb 2020 11:19:23.353 # +try-failover master mymaster 127.0.0.1 6379
9792:X 02 Feb 2020 11:19:23.431 # +vote-for-leader 3b9f4dfc0dcf08b0d21478cf58d0227e1ba61564 6
9792:X 02 Feb 2020 11:19:23.431 # +elected-leader master mymaster 127.0.0.1 6379
9792:X 02 Feb 2020 11:19:23.431 # +failover-state-select-slave master mymaster 127.0.0.1 6379
9792:X 02 Feb 2020 11:19:23.523 # +selected-slave slave 127.0.0.1:6378 127.0.0.1 6378 @ mymaster 127.0.0.1 6379
9792:X 02 Feb 2020 11:19:23.524 * +failover-state-send-slaveof-noone slave 127.0.0.1:6378 127.0.0.1 6378 @ mymaster 127.0.0.1 6379
9792:X 02 Feb 2020 11:19:23.617 * +failover-state-wait-promotion slave 127.0.0.1:6378 127.0.0.1 6378 @ mymaster 127.0.0.1 6379
9792:X 02 Feb 2020 11:19:24.611 # +promoted-slave slave 127.0.0.1:6378 127.0.0.1 6378 @ mymaster 127.0.0.1 6379
9792:X 02 Feb 2020 11:19:24.612 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6379
9792:X 02 Feb 2020 11:19:24.659 * +slave-reconf-sent slave 127.0.0.1:6377 127.0.0.1 6377 @ mymaster 127.0.0.1 6379
9792:X 02 Feb 2020 11:19:25.605 * +slave-reconf-inprog slave 127.0.0.1:6377 127.0.0.1 6377 @ mymaster 127.0.0.1 6379
9792:X 02 Feb 2020 11:19:25.606 * +slave-reconf-done slave 127.0.0.1:6377 127.0.0.1 6377 @ mymaster 127.0.0.1 6379
9792:X 02 Feb 2020 11:19:25.671 # +failover-end master mymaster 127.0.0.1 6379
9792:X 02 Feb 2020 11:19:25.672 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6378
9792:X 02 Feb 2020 11:19:25.672 * +slave slave 127.0.0.1:6377 127.0.0.1 6377 @ mymaster 127.0.0.1 6378
9792:X 02 Feb 2020 11:19:25.673 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6378
- 执行用户请求“ mymaster”的故障转移,然后进入了一个新纪元。
- 因为是sentinel1提出的故障转移,所以它就先索要投票(根据之前的理论可知sentinel1将当选领导),事实也是这样,3b9f4dfc0dcf08b0d21478cf58d0227e1ba61564就是sentinel1的ID。
- 开始故障转移,从slave节点中选择出一个来作为新的master。因为salve1也就是地址为6378的节点优先级最高,那么它将被选出来然后提升为新的master节点,然后重新分配从属关系,将剩余的从节点作为新的master的从节点,原先的master也作为新master的从节点。
- sentinel执行switch-master将slave1切换为新的master,并通知应用方master的更改和其它sentinel更新配置。
此时再执行info sentinel会发现master节点已经更改。
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=127.0.0.1:6378,slaves=2,sentinels=3
再去查看slave2的配置文件,会发现slaveof配置被移除了,换成了以下配置。
# 这个是新的master的地址和端口,说明salve2是在复制这个新master
# 而且可以看到它是被配置重写自动生成的
# Generated by CONFIG REWRITE
replicaof 127.0.0.1 6378
master.conf也一样,因为它现在是新master的从节点,也被写入了上面这个配置。
真实宕机
先查看一下当前redis的进程:
$ ps -ef | grep redis
root 9523 1 0 Feb01 ? 00:00:20 redis-server *:6377
root 9792 1 0 Feb01 ? 00:00:28 redis-server *:26379 [sentinel]
root 9810 1 0 Feb01 ? 00:00:29 redis-server *:26378 [sentinel]
root 9821 1 0 Feb01 ? 00:00:28 redis-server *:26377 [sentinel]
monk-jay 9889 8399 0 Feb01 tty4 00:00:00 redis-cli -p 26379
root 10039 1 0 Feb01 ? 00:00:10 redis-server *:6379
root 10105 1 0 Feb01 ? 00:00:16 redis-server *:6378
monk-jay 10254 8035 0 11:44 tty2 00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn redis
因为我当前的master的端口是6378,所以我现在将它对应的进程杀死。
# 10105是6378端口这个进程对应的pid
sudo kill -9 10105
再次输入ps -ef | grep redis
可以看到6378端口对应的进程已经没了,模拟真实的宕机。
下面来看看sentinel的日志:
9810:X 02 Feb 2020 11:47:08.158 # +sdown master mymaster 127.0.0.1 6378
9810:X 02 Feb 2020 11:47:08.231 # +odown master mymaster 127.0.0.1 6378 #quorum 2/2
9810:X 02 Feb 2020 11:47:08.231 # +new-epoch 7
9810:X 02 Feb 2020 11:47:08.231 # +try-failover master mymaster 127.0.0.1 6378
9810:X 02 Feb 2020 11:47:08.339 # +vote-for-leader 0bf2c2c19fcb5e0a77a79485ea7f2d8d012a03d8 7
9810:X 02 Feb 2020 11:47:08.367 # 7ea991444528f91b83fb86534dcb7db28e862507 voted for 7ea991444528f91b83fb86534dcb7db28e862507 7
9810:X 02 Feb 2020 11:47:08.421 # 3b9f4dfc0dcf08b0d21478cf58d0227e1ba61564 voted for 0bf2c2c19fcb5e0a77a79485ea7f2d8d012a03d8 7
9810:X 02 Feb 2020 11:47:08.451 # +elected-leader master mymaster 127.0.0.1 6378
9810:X 02 Feb 2020 11:47:08.451 # +failover-state-select-slave master mymaster 127.0.0.1 6378
9810:X 02 Feb 2020 11:47:08.507 # +selected-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6378
9810:X 02 Feb 2020 11:47:08.507 * +failover-state-send-slaveof-noone slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6378
9810:X 02 Feb 2020 11:47:08.563 * +failover-state-wait-promotion slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6378
9810:X 02 Feb 2020 11:47:09.443 # +promoted-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6378
9810:X 02 Feb 2020 11:47:09.444 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6378
9810:X 02 Feb 2020 11:47:09.460 * +slave-reconf-sent slave 127.0.0.1:6377 127.0.0.1 6377 @ mymaster 127.0.0.1 6378
9810:X 02 Feb 2020 11:47:10.423 * +slave-reconf-inprog slave 127.0.0.1:6377 127.0.0.1 6377 @ mymaster 127.0.0.1 6378
9810:X 02 Feb 2020 11:47:10.424 * +slave-reconf-done slave 127.0.0.1:6377 127.0.0.1 6377 @ mymaster 127.0.0.1 6378
9810:X 02 Feb 2020 11:47:10.490 # +failover-end master mymaster 127.0.0.1 6378
9810:X 02 Feb 2020 11:47:10.490 # +switch-master mymaster 127.0.0.1 6378 127.0.0.1 6379
9810:X 02 Feb 2020 11:47:10.491 * +slave slave 127.0.0.1:6377 127.0.0.1 6377 @ mymaster 127.0.0.1 6379
9810:X 02 Feb 2020 11:47:10.491 * +slave slave 127.0.0.1:6378 127.0.0.1 6378 @ mymaster 127.0.0.1 6379
9810:X 02 Feb 2020 11:47:40.537 # +sdown slave 127.0.0.1:6378 127.0.0.1 6378 @ mymaster 127.0.0.1 6379
可以看到第一行,显示sdown,说明sentinel1主观下线了当前master。然后sentinel们开始协商master的状态,有大于等于quorum个sentinel认为master已经挂了,所以sentinel客观下线了master。然后进入了一个新纪元。其它的就跟上面模拟宕机的一样啦。