可以开启两个实例, 一个master, 一个slave,同时开启sentinel。在master崩溃的情况下,sentinel可以将slave切换为master,保证服务正常进行。

环境模拟

redis2.8.17。开启两个实例,一个master,一个slave。

  • master (127.0.0.1 6379)
    修改mater的配置文件master.conf,添加以下命令

    1
    2
    3
    # redis在后台运行
    daemonize yes
    pidfile "/var/run/master.pid"
  • slave (127.0.0.1 6380)

在slave的配置文件slave.conf中添加以下命令:

1
2
3
4
daemonize yes
port 6380
pidfile "/var/run/slave.pid"
slaveof 127.0.0.1 6379
  • sentinel

在sentinel的配置文件sentinel.conf中添加以下命令:

1
sentinel monitor mymaster 127.0.0.1 6379 1

该指令格式为:SENTINEL MONITOR <name> <ip> <port> <quorum>
<quorum>指定必须有指定数目的sentinel认定当前master处于ODOWN状态,才能进行failover。
由于我只配置了一个sentinel,在我的配置中该值指定为1。只要sentinel认定master处于ODOWN状态,即可进行failover。

注: 如果想让sentinel像其它的redis实例一样在后台运行,可以在配置文件中添加daemonize yes命令。(来源 )根据redis作者的说法,基本上redis.conf使用的命令在sentinel中都可以使用。

实验过程

1. 启动master和slave

1
2
# ./redis-server master.conf
# ./redis-server slave.conf

2. 启动sentinel

1
# ./redis-sentinel sentinel.conf

sentinel会自动查找当前master的slave。

3. 关闭master实例

1
# ./redis-cli -p 6379 shutdown

sentinel打出的log如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[12619] 07 Nov 18:13:58.818 # +sdown master mymaster 127.0.0.1 6379
[12619] 07 Nov 18:13:58.818 # +odown master mymaster 127.0.0.1 6379 #quorum 1/1
[12619] 07 Nov 18:13:58.818 # +new-epoch 2
[12619] 07 Nov 18:13:58.818 # +try-failover master mymaster 127.0.0.1 6379
[12619] 07 Nov 18:13:58.821 # +vote-for-leader 71a815d5be09345037e958f8b8b117aef2da5834 2
[12619] 07 Nov 18:13:58.821 # +elected-leader master mymaster 127.0.0.1 6379
[12619] 07 Nov 18:13:58.821 # +failover-state-select-slave master mymaster 127.0.0.1 6379
[12619] 07 Nov 18:13:58.897 # +selected-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
[12619] 07 Nov 18:13:58.897 * +failover-state-send-slaveof-noone slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
[12619] 07 Nov 18:13:58.997 * +failover-state-wait-promotion slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
[12619] 07 Nov 18:13:59.882 # +promoted-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
[12619] 07 Nov 18:13:59.882 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6379
[12619] 07 Nov 18:13:59.934 # +failover-end master mymaster 127.0.0.1 6379
[12619] 07 Nov 18:13:59.934 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380
[12619] 07 Nov 18:13:59.934 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380
[12619] 07 Nov 18:14:29.959 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380

当master实例不可用时,sentinel将slave选为新的master。

4. 重启原master实例

此时sentinel的log如下:

1
[12619] 07 Nov 18:26:35.900 * +convert-to-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380

原master重启之后被sentinel设置为了新的slave,完成了主从切换。

解释

当有<quorum>个sentinel认定当前的master不可用时,sentinel们会选出一个sentinel进行failover。被选中的sentinel会从slave中选出一个作为新的master,并将新master的配置信息传输给其它的slave。原master重启后会被sentinel设置为当前master的slave。
详细文档请见: 链接

PHP实现的sentinel client

暂时只找到这一个,链接
在原master挂掉之后,客户端代码需要通过sentinel获取最新的master配置信息。