12-马上上手
8.2.2 马上上手
在理解哨兵的原理前,我们首先实际使用一下哨兵,来了解哨兵是如何工作的。为了简单起见,我们将以图8-2所示的架构为例进行模拟。首先按照8.1节介绍的方式建立起3个Redis实例,其中包括一个主数据库和两个从数据库。主数据库的端口为6379,两个从数据库的端口分别为6380和6381。我们使用Redis命令行客户端来获取复制状态,以保证复制配置正确。
首先是主数据库:
redis 6379> INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=10125,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=10125,lag=1
可见其连接了两个从数据库,配置正确。然后用同样的方法查看两个从数据库的配置:
redis 6380> INFO replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
redis 6381> INFO replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
当出现的信息如上时,即证明一主二从的复制配置已经成功了。
接下来开始配置哨兵。建立一个配置文件,如sentinel.conf,内容为:
sentinel monitor mymaster 127.0.0.1 6379 1
其中 mymaster 表示要监控的主数据库的名字,可以自己定义一个。这个名字必须仅由大小写字母、数字和“.-_”这3个字符组成。后两个参数表示主数据库的地址和端口号,这里我们要监控的是主数据库6379。最后的1表示最低通过票数,后面会介绍。接下来执行来启动Sentinel进程,并将上述配置文件的路径传递给哨兵:
$ redis-sentinel /path/to/sentinel.conf
需要注意的是,配置哨兵监控一个系统时,只需要配置其监控主数据库即可,哨兵会自动发现所有复制该主数据库的从数据库,具体原理后面会详细介绍。
启动哨兵后,哨兵输出如下内容:
[71835] 19 Feb 22:32:28.730 # Sentinel runid is e3290844c1a404699479771846b716c7fc830e80
[71835] 19 Feb 22:32:28.730 # +monitor master mymaster 127.0.0.1 6379 quorum 1
[71835] 19 Feb 22:33:09.997 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
[71835] 19 Feb 22:33:30.068 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
其中 +slave 表示新发现了从数据库,可见哨兵成功地发现了两个从数据库。现在哨兵已经在监控这3个Redis实例了,这时我们将主数据库(即运行在6379端口上的Redis实例)关闭(杀死进程或使用 SHUTDOWN 命令),等待指定时间后(可以配置,默认为30秒),哨兵会输出如下内容:
[71835] 19 Feb 22:36:03.780 # +sdown master mymaster 127.0.0.1 6379
[71835] 19 Feb 22:36:03.780 # +odown master mymaster 127.0.0.1 6379 #quorum 1/1
其中 +sdown 表示哨兵主观认为主数据库停止服务了,而 +odown 则表示哨兵客观认为主数据库停止服务了,关于主观和客观的区别后文会详细介绍。此时哨兵开始执行故障恢复,即挑选一个从数据库,将其升格为主数据库。同时输出如下内容:
[71835] 19 Feb 22:36:03.780 # +try-failover master mymaster 127.0.0.1 6379
……
[71835] 19 Feb 22:36:05.913 # +failover-end master mymaster 127.0.0.1 6379
[71835] 19 Feb 22:36:05.913 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380
[71835] 19 Feb 22:36:05.914 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
[71835] 19 Feb 22:36:05.914 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380
+try-failover 表示哨兵开始进行故障恢复, +failover-end 表示哨兵完成故障恢复,期间涉及的内容比较复杂,包括领头哨兵的选举、备选从数据库的选择等,放到后面介绍,此处只需要关注最后3条输出。 +switch-master 表示主数据库从6379端口迁移到6380端口,即6380端口的从数据库被升格为主数据库,同时两个 +slave 则列出了新的主数据库的两个从数据库,端口分别为6381和6379。其中6379就是之前停止服务的主数据库,可见哨兵并没有彻底清除停止服务的实例的信息,这是因为停止服务的实例有可能会在之后的某个时间恢复服务,这时哨兵会让其重新加入进来,所以当实例停止服务后,哨兵会更新该实例的信息,使得当其重新加入后可以按照当前信息继续对外提供服务。此例中6379端口的主数据库实例停止服务了,而6380端口的从数据库已经升格为主数据库,当6379端口的实例恢复服务后,会转变为6380端口实例的从数据库来运行,所以哨兵将6379端口实例的信息修改成了6380端口实例的从数据库。
故障恢复完成后,可以使用Redis命令行客户端重新检查6380和6381两个端口上的实例的复制信息:
redis 6380> INFO replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=270651,lag=1
redis 6381> INFO replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
可以看到6380端口上的实例已经确实升格为主数据库了,同时6381端口上的实例是其从数据库。整个故障恢复过程就此完成。
那么此时我们将6379端口上的实例重新启动,会发生什么情况呢?首先哨兵会监控到这一变化,并输出:
[71835] 19 Feb 23:46:14.573 # -sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380
[71835] 19 Feb 23:46:24.504 * +convert-to-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380
-sdown 表示实例6379已经恢复服务了(与 +sdown 相反),同时 +convert-to-slave 表示将6379端口的实例设置为6380端口实例的从数据库。这时使用Redis命令行客户端查看6379端口实例的复制信息为:
redis 6379> INFO replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
同时6380端口实例的复制信息为:
redis 6380> INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=292948,lag=1
slave1:ip=127.0.0.1,port=6379,state=online,offset=292948,lag=1
正如预期一样,6380端口实例的从数据库变为了两个,6379成功恢复服务。