redis主从模式解决了数据备份和单例可能存在的性能问题,但是其也引入了新的问题。
由于主从模式配置了三个redis实例,并且每个实例都使用不同的ip(如果在不同的机器上)和端口号。
根据前面所述,主从模式下可以将读写操作分配给不同的实例进行从而达到提高系统吞吐量的目的,但也正是因为这种方式造成了使用上的不便,因为每个客户端连接redis实例的时候都是指定了ip和端口号的,如果所连接的redis实例因为故障下线了,而主从模式也没有提供一定的手段通知客户端另外可连接的客户端地址,因而需要手动更改客户端配置重新连接。
另外,主从模式下,如果主节点由于故障下线了,那么从节点因为没有主节点而同步中断,因而需要人工进行故障转移工作。
为了解决这两个问题,在2.8版本之后redis正式提供了sentinel(哨兵)架构。关于sentinel,这里需要说明几个概念:
每个sentinel节点其实就是一个redis实例,与主从节点不同的是sentinel节点作用是用于监控redis数据节点的,而sentinel节点集合则表示监控一组主从redis实例多个sentinel监控节点的集合,比如有主节点master和从节点slave-1、slave-2。
为了监控这三个主从节点,这里配置N个sentinel节点sentinel-1,sentinel-2,...,sentinel-N。
如下图是sentinel监控主从节点的示例图:
从图中可以看出,对于一组主从节点,sentinel只是在其外部额外添加的一组用于监控作用的redis实例。
在主从节点和sentinel节点集合配置好之后,sentinel节点之间会相互发送消息,以检测其余sentinel节点是否正常工作,并且sentinel节点也会向主从节点发送消息,以检测监控的主从节点是否正常工作。
前面讲到,sentinel架构的主要作用是解决主从模式下主节点的故障转移工作的。
这里如果主节点因为故障下线,那么某个sentinel节点发送检测消息给主节点时;
如果在指定时间内收不到回复,那么该sentinel就会主观的判断该主节点已经下线,那么其会发送消息给其余的sentinel节点,询问其是否“认为”该主节点已下线,其余的sentinel收到消息后也会发送检测消息给主节点;
如果其认为该主节点已经下线,那么其会回复向其询问的sentinel节点,告知其也认为主节点已经下线,当该sentinel节点最先收到超过指定数目(配置文件中配置的数目和当前sentinel节点集合数的一半,这里两个数目的较大值)的sentinel节点回复说当前主节点已下线,那么其就会对主节点进行故障转移工作。
故障转移的基本思路是在从节点中选取某个从节点向其发送slaveof no one(假设选取的从节点为127.0.0.1:6380),使其称为独立的节点(也就是新的主节点),然后sentinel向其余的从节点发送slaveof 127.0.0.1 6380命令使它们重新成为新的主节点的从节点。
重新分配之后sentinel节点集合还会继续监控已经下线的主节点(假设为127.0.0.1:6379),如果其重新上线,那么sentinel会向其发送slaveof命令,使其成为新的主机点的从节点,如此故障转移工作完成。
上面我们讲到了,每个sentinel节点在本质上还是一个redis实例,只不过和redis数据节点不同的是,其主要作用是监控redis数据节点。
在redis安装目录下有个默认的sentinel配置文件sentinel.conf,和配置主从节点类似,这里复制三个配置文件:sentinel-26379.conf,sentinel-26380.conf和sentinel-26381.conf。分别按照如下示例编辑这三个配置文件: