一、定义
上一次我们讲过redis的主从复制存在一个很大的问题,就是主节点遇到故障只能手动恢复,而redis sentinel正是为了解决这一问题出现的。sentinel的核心功能就是通过对主从节点的监控实现及时发现主节点故障并自动故障转移的功能。sentinel实际上是特殊的redis节点,只是不存储数据。启动方式类似redis:./redis-sentinel sentinel.conf <==指定配置文件
架构:sentinel的架构主要由客户端、哨兵节点、主从数据节点三部分组成,其中哨兵节点由一个或多个哨兵节点组成,数据节点由主从节点组成。而客户端(如jedis等)直接连接sentinel集群,通过sentinel获取redis主从节点的信息,再对reids进行操作。sentinel能够获取redis的主从运行状态,在主从遇到问题时自动做出相应处理并通知客户端使其知道哪些redis可操作。
其主要有如下几个功能:
二、sentinel的故障转移过程
说明:
(1)主观、客观下线
主观下线:表示每个sentinel节点对redis节点宕机的偏见,即一个sentinel节点“主观地”判断下线。对应的配置为 sentinel down-after-milliseconds mymaster 30000 ,即当某个sentinel节点根据定时任务的心跳检测在30秒内没有连上redis节点则其认为该redis不可用,但是有可能是网络原因只有它一个sentinel连接不上,不一定redis就真的不可用,因此才称为主观(该节点认为)下线。
客观下线:主节点才有的概念,所有sentinel节点对redis主节点不可用达成共识(超过quorun个sentinel觉得主节点不可用),对应的配置为 sentinel monitor mymaster 127.0.0.1 6379 2 ,有sentinel节点在对主节点进行主观下线后(其他节点不会有该操作),会通过sentinel is-master-down-by-addr 命令询问其他sentinel节点该主节点的状态,如果判断主节点下线的sentinel数量达到2(该值跟上面配置有关),则对该主节点进行客观下线(主节点真正不可用了)。
(2)sentinel领导选举
当sentinel集群认为主节点客观下线后,所有sentinel会选举一个领导者sentinel节点对主节点进行故障转移,选举使用的是Raft算法即先到先得,流程如下:
(3)slave节点成为新master的选择方法
三、sentinel的定时任务
每个哨兵(sentinel)节点维护了3个如下的定时任务:
四、客户端实现原理及java代码实现
java等客户端通过sentinel操作redis的实现原理:
即客户端需要知道 sentinel地址集合、mastername,另外要注意客户端连接不是代理模式,最终还是直接连接到master节点进行操作,代码如下:
public static void connSentinels(){
String masterName = "mymaster"; //对应的master节点名称
Set sentinels = new HashSet(); //sentinels节点集群
sentinels.add("192.168.1.1:26379");
sentinels.add("192.168.1.1:26380");
sentinels.add("192.168.1.1:26381");
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();//此处对poolConfig进行设置
JedisSentinelPool sentinelPool = new JedisSentinelPool(masterName, sentinels, poolConfig); //初始化过程做了很多工作
Jedis jedis = null;
try{
jedis = sentinelPool .getResource(); //使用jedis进行操作,用完直接close即可,会自动判断,若单个连接则关闭,在连接池内则归还
jedis.set("key1", "value1");
}catch(Exception e){
}finally{
//close jedis
}
}
五、配置
1、sentinel monitor {masterName} {masterIp} {masterPort} {quorum}:如 sentinel monitor mymaster 127.0.0.1 6379 2 ,这是sentinel最重要的一个配置,其中masterName为对应主节点的名称,masterIp为主节点的ip,masterPort为主节点的端口,quorum为多少sentinel觉得该主节点下线则对主节点进行客观下线,一般设置为sentinel节点数的一半加1,如上面表示至少需要2个哨兵节点同意主节点下线,才能判定主节点故障并进行故障转移。
2、sentinel down-after-milliseconds {masterName} {time}:如 sentinel down-after-milliseconds mymaster 30000,该配置与主观下线的判断有关,sentinel通过ping对其他节点进行心跳检测,当被ping节点time时间内没回复则sentinel将其进行主观下线,其对主、从节点和sentinel节点的主观下线判定都有效。可根据网络等因素调整该值,越大则主观下线判定更宽松,误判几率降低,但会导致故障发现和转移时间加长。默认值是30000,即30s。
3、sentinel parallel-syncs {masterName} {number}:如sentinel parallel-syncs mymaster 1,故障转移后需要进行主从复制,该参数规定每次向新的主节点发起复制的从节点数,上面例子表示从节点修改master之后一次只进行一次主从复制。如果故障转移新主节点切换后,有5个从节点要进行复制,则从节点会number个从节点一起复制,即一次最多number个。设置过高虽然恢复时间快,但对主节点的硬盘及网络负载较大, 默认值是1。
4、sentinel failover-timeout {masterName} {time}:如sentinel failover-timeout mymaster 180000,该配置与故障转移超时的判断有关,但是该参数不是用来判断整个故障转移阶段的超时,而是其几个子阶段的超时,例如如果主节点晋升从节点时间超过time,或从节点向新的主节点发起复制操作的时间(不包括复制数据的时间)超过time,都会导致故障转移超时失败。failover-timeout的默认值是180000,即180s;如果超时,则下一次该值会变为原来的2倍。
六、实例说明
以三个sentinel(端口:26379/26380/26381)节点,三个redis(6379/6380/6381)节点的配置如下(持久化等其他配置这里不涉及):
(1)redis主节点配置(端口为6379)
port 6379
daemonize yes
logfile “6379.log”
dir “/home/me/redis”
(2)redis 两个从节点配置(端口为6380、6381,配置除了端口基本相同,只列一个)
port 6380
daemonize yes
logfile “6380.log”
dir “/home/me/redis”
slaveof 127.0.0.1 7000
(3)sentinel主要配置(只写出其中一个,默认配置文件为sentinel.conf)
port 26379
dir “/home/me/sentinels”
logfile “26379.log”
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
(4)通过 ./redis-sentinel sentinel.conf 启动sentinel,启动后再打开该配置文件,会看到多了从节点等信息。
(5)通过 ./redis-cli -p 26379 ,可以登录到sentinel并进行命令操作,因为其无存储,进行set操作将报错。可进行如下命令:
七、其他
(1)sentinel节点本质上是没有存储能力的redis节点。
(2)客户端初始化连接的是sentinel节点集合不是具体的redis节点,但sentinel只是配置中心不是代理。即客户端在通过sentinel获得主节点信息后,会直接建立到主节点的连接,后续的请求(如set/get)会直接发向主节点;如果是代理,客户端的每一次请求都会发向哨兵,哨兵再通过主节点处理请求。
(3)在故障转移阶段,sentinel和主从节点的配置文件都会被改写
(4)sentinel节点的数量应该是奇数,便于哨兵通过投票做出“决策”,领导者选举的决策、客观下线的决策等。
(5)sentinel是一个分布式系统,可以部署多个sentinel实例来监控同一组Redis实例,只有一个sentinel实例也可实现所有功能,只是不能对sentinel高可用。
(6)sentinel存在的问题:仍然没有解决写操作无法负载均衡、及存储能力受到单机限制的问题