复述,作为内存数据库,需要具备高可用的特点,不然如果服务器宕机,还在内存里的数据就会丢失。我们最常用的高可用方法就是搭建集群,主机器挂了,可以让奴隶机器顶上,继续提供服务。但是复述,集群是不会自动进行主从切换的,也就是说,如果主节点非常不争气的在凌晨3点挂了,那么运维同学就要马上起的床,把从节点改成主节点,这样的操作是非常繁琐低效的。为此,复述,官方提供了一种解决方案:复述,哨兵
复述,哨兵集群通常由3到5个节点组成,如果个别节点挂了,集群还可以正常运作。它负责监控复述,集群的健康情况。如果主节点挂掉,哨兵集群会通过投票选择一个新的主节点。当原来的主节点恢复时,它会被当做新的主节点的从节点重新加入复述,集群。
标记集群通过指定的配置文件发现主人,对其进行监控,并且会发送信息指令获取主人的从节点信息.Sentinel集群中的节点通过向其监控的主从节点发送你好信息(包含铁卫军本身的ip,端口和id等内容)来向其他哨兵宣告自己的存在。
标记集群通过订阅连接来接收其他前哨的你好信息。
标记集群通过平命令来检查监控的实例状态,如果在指定时间内没有返回,则认为该实例下线。
哨兵触发故障转移主从切换后,并不会马上进行,只有指定(群体)前哨授权后,主节点被标记为ODOWN状态。这时才真正开始投票选择新的主人。
哨兵选择新的主人的原则是:首先判断优先级,选择优先级较小的,如果优先级相同,查看复制下标,选择复制数据较多的,如果复制下标也相同,就选择进程ID较小的。
哨兵被授权后,它将会获得宕掉的主的一份最新配置版本号(config-epoch),当故障转移执行结束以后,这个版本号将会被用于最新的配置,通过广播形式通知其它前哨,其它的哨兵则更新对应掌握的配置。
我们以Python为例,简单说明一下在客户端如何使用哨兵
复述。哨兵进口哨兵 if __name__==癬_main__”: 哨兵=前哨(“localhost”, 26379年,socket_timeout=0.1) print (sentinel.discover_master (mymaster)) print (sentinel.discover_slaves (mymaster)) 主=前哨。master_for (mymaster, socket_timeout=0.1) 奴隶=前哨。slave_for (mymaster, socket_timeout=0.1) 的主人。集(“跟随”,“Jackeyzhe2018”) 遵循=slave.get(“跟随”) print ()
master_for和slave_for方法会从连接池中拿出一个连接来使用,如果从地址有多个,则会采用轮询的方法。
当复述,发生了主从切换时,客户端如何知道地址已经变更了呢?我们从redis-py的源码里找一找答案。
可以看的到,复述,在创建一个新的连接时,会调用get_master_address方法来获取主节点地址.get_master_address方法中,客户端先查询主节点地址,然后与内存中的地址进行比较。如果不一致,则会断开连接,然后使用新的地址重新进行连接。
如果主节点没有挂,而前哨主动进行了主从切换,对于这种情况redis-py也做了处理。就是捕获一个ReadOnlyError的异常,然后断开连接,后续指令都需要重新进行连接了。当然,如果没有修改性指令,那么连接就不会切换,不过数据也不会被破坏,所以影响不大。
关于哨兵的工作原理和使用方法我们已经有了大概的认识,为了加深理解,我们来自己动手搭建一套哨兵集群。
首先搭建我们我需要的复述,集群环境
安装好复述后,将复述,目录下的配置文件redis.conf复制3份,分别命名为redis6379.conf, redis6380.conf redis6381.conf。
在redis6381.conf文件中修改以下几项
绑定127.0.0.1 端口6381 日志文件“6381.日志” dbfilename“dump - 6381. - rdb”
在redis6379.conf中修改
绑定127.0.0.1 端口6379 日志文件“6379.日志” dbfilename“dump - 6379. - rdb” slaveof 127.0.0.1 6381
redis6380.conf的修改参照redis6379.conf。修改完成后,分别启动三个实例。就搭建好了我们想要的复述,主从环境了。