Redis Sentinel是一个分布式架构,包含若干个Sentinel节点和Redis数据节点,每个Sentinel节点会对数据节点和其余Sentinel节点进行监控,当发现节点不可达时,会对节点做下线标识。
每个sentinel节点其实就是一个redis实例,与主从节点不同的是sentinel节点作用是用于监控redis数据节点的,而sentinel节点集合则表示监控一组主从redis实例多个sentinel监控节点的集合,比如有主节点master和从节点slave-1、slave-2,为了监控这三个主从节点,这里配置N个sentinel节点sentinel-1,sentinel-2,...,sentinel-N。如下图是sentinel监控主从节点的示例图:
哨兵模式的提出基于下面两个考虑:
一方面由于主从模式启动了多个redis实例,并且每个实例都使用不同的ip(如果在不同的机器上)和端口号,根据前面所述,因为每个客户端连接redis实例的时候都是指定了ip和端口号的,如果所连接的redis实例因为故障下线了,而主从模式也没有提供一定的手段通知客户端另外可连接的redis地址,因而需要手动更改客户端连接配置重新连接。
另一方面主从模式下,如果主节点由于故障下线了,那么从节点因为没有主节点而同步中断,因而需要人工进行故障转移(failover)工作。
为了解决这两个问题,在2.8版本之后redis正式提供了sentinel(哨兵)架构。
下面通过部署一个Redis Sentinel实例来了解整体框架,角色分配及IP、端口信息如下
3个Sentinel节点的部署方法是相同的(端口不同)。在redis安装目录下有个默认的sentinel配置文件sentinel.conf,分别复制为3各文件26379.conf、26380.conf和26381.conf,修改26279.conf配置为
// Sentinel节点的端口
port 26379
dir /var/redis/data/
logfile "26379.log"
// 当前Sentinel节点监控 127.0.0.1:6379 这个主节点
// 2代表判断主节点失败至少需要2个Sentinel节点节点同意
// mymaster是主节点的别名
sentinel monitor mymaster 127.0.0.1 6379 2
//每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30000毫秒且没有回复,则判定不可达
sentinel down-after-milliseconds mymaster 30000
//当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1
sentinel parallel-syncs mymaster 1
//故障转移超时时间为180000毫秒
sentinel failover-timeout mymaster 180000
对于端口为26380和26381的sentinel,其配置和上述类似,只需要把相应的端口号修改为对应的端口号即可。参数中sentinel monitor mymaster 127.0.0.1 6379 2这里的端口号6379是不用更改的,因为sentinel是通过检测主节点的状态来得知当前主节点的从节点有哪些的,因而设置为主节点的端口号即可。配置完成后我们首先启动三个主从节点,然后分别使用三个配置文件使用如下命令启用sentinel:
[root@localhost ~]#/usr/local/redis-2.6.14/src/redis-sentinel /usr/local/redis-2.6.14/26379.conf
[root@localhost ~]#/usr/local/redis-2.6.14/src/redis-sentinel /usr/local/redis-2.6.14/26380.conf
[root@localhost ~]#/usr/local/redis-2.6.14/src/redis-sentinel /usr/local/redis-2.6.14/26381.conf
看下监控结点的工作状态
[root@localhost redis-2.6.14]# ./src/redis-cli -h127.0.0.1 -p 26379
redis 127.0.0.1:26379>
redis 127.0.0.1:26379>
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3
redis 127.0.0.1:26379>
最后一行,name=mymaster,说明主节点名称叫做mymastr;slaves=2,说明主节点有2个从节点;sentinels=3说明启动了3个哨兵结点。
现在模拟主结点故障,手动kill掉6379端口进程。当主节点下线时长超过配置的下线时长30000秒,Redis Sentinel执行故障转移操作。
此时,我们查看一下Sentinel节点监控的主节点信息:
redis 127.0.0.1:26379> sentinel masters
1) 1)"name"
2)"mymaster"
3)"ip"
4)"127.0.0.1"
5)"port"
6)"6381"
7)"runid"
8)"74cc6983cee3e6574b72f47f9119662e7ec5d332"
9)"flags"
10)"master"
…
从上面看,6381结点现在成为主结点。再看一下Sentinel节点监控的从节点信息:
redis 127.0.0.1:26379> sentinel slaves mymaster
1) 1)"name"
2)"127.0.0.1:6379"
3)"ip"
4)"127.0.0.1"
5)"port"
6)"6379"
7)"runid"
8)""
9)"flags"
10)"s_down,slave,disconnected,demote" //端口6379的原主节点已经断开了连接
….
2) 1)"name"
2)"127.0.0.1:6380"
3)"ip"
4)"127.0.0.1"
5)"port"
6)"6380"
7)"runid"
8)"aea10a0389fade1b2ab262f0c5cbf8d889b086f2"
9)"flags"
10)"slave" //本来的从节点,还是从节点的role
……
同样从节点只能读、不能写及删除,否则报:(error) READONLY You can't write against a read only slave.)。