Redis_Sentinel
Redis集群的主从复制
在redis主从复制中,如果某个节点挂掉了,需要我们去写手动写脚本,来时转移节点。
Redis Sentinel的功能:对Redis节点进行监控,故障判断,故障转移,故障通知
同时多个sentinel运行,即使一个sentinel进程运行异常,还有别的sentinel继续运行,可以保证对故障节点判断的准确性,同时保证Redis的高可用
对于redis-cli来说,Redis cli不会再记录Redis的IP和端口,而是从sentinel获取Redis信息,然后进行连接Redis节点,进行数据写入和读取操作
多个Redis Sentinel对所有的master和slave进行监控,会实时记录master和slave的地址信息
Redis Sentinel就是一种高可用的架构:
      
有很多sentinel节点,它不用存储数据,主要监控redis节点是否发生故障并且通知客户端。
redis Sentinel如何做到自动高可用故障转移:
     
具体流程
1.当某个master发生故障,多个sentinel会监控到这个异常,这些sentinel会按照一定规则从多个slave中选中一个做为新的master,并通知别的slave从新的master中同步数据 2.当某个slave转换为新的master,sentinel会记录新的master的地址信息和slave的地址信息,通知Redis cli 3.Redis cli接收到新的master和slave的信息,就会向新的master写入数据,从slave中读取数据 4.等到原来的master重启之后,会变成新的master的slave,并从新的master同步数据
同样一个sentinel可以对多组master-slave做监控。
当master节点宕掉的时候:
1.sentinel节点会从slave节点中选择一个合适的节点作为新的master节点。
2.对上面选出的slave节点执行slaveof no one命令让其成为master节点。
3.向剩余的slave节点发送命令,让他们成为新master节点的slave节点,复制规则和parallel-syncs参数有关。
4.更新对原来master节点配置为slave,并保持对其“关注”,当其恢复后,命令它去复制新的master节点。
Redis Sentinel实现原理:Redis Sentinel内部有三个定时任务来对redid节点进行故障判断和转移
  1.每10秒每个sentinel对master和slave执行info命令,以发现slave节点和确认主从关系,sentinel在master节点执行info replication命令,从命令执行结果中解析出slave节点
     
  2.每2秒每个sentinel通过master节点的channel交换信息(发布订阅),master节点上有一个发布订阅的channel频道:__sentinel__:hello,用于所有sentinel之间进行信息交换
一个sentinel发布消息,消息包含当前sentinel节点的信息,对其他sentinel节点的判断以及当前sentinel对master节点和slave节点的一些判断,其他sentinel都可以接收到这条消息,新加入sentinel节点时,sentinel节点之间可以相互感知,以达到信息交互的功能
   
3.每1秒每个sentinel对其他sentinel节点和Redis节点执行ping操作,每个sentinel都可以知道其他sentinel节点,当监控的master发生故障时,方便进行判断和新master的挑选,这个定时任务是master进行故障判定的依据
       
主观下线和客观下线:
主观下线:每个sentinel节点对Redis节点失败的'偏见'
Sentinel的配置中有一个down-after-milliseconds的时间:
每个sentinel每秒对master和slave执行ping操作,当sentinel对master或slave在timeout定义的毫秒时间内没有回复,则sentinel会认为这个节点已经被主观下线了
客观下线:
sentinel集合监控名为mymaster的master,slave节点 被监控的master节点的IP地址是192.168.81.100,端口为6379, sentinel会在`__sentinel__:hello`频道中交流对master节点的看法,如果sentinel节点都对master节点ping失败'达成共识',sentinel个数超过quorum(一般是sentinel节点个数一半)的个数,sentinel集合则会认为master节点客观下线
sentinel领导者选举具体过程:
1.每个做主观下线的sentinel节点向其他sentinel节点发送命令,要求将自己设置为领导者 2.收到命令的sentinel节点如果没有同意同意其他sentinel节点发送的命令,那么将同意该请求,否则拒绝 3.如果该sentinel节点发现自己的票数已经超过sentinel集合半数且超过quorum,将成为领导者 4.如果此过程中有多个sentinel节点成为领导者,那么将等待一段时间重新进行选举
故障的转移由sentinel领导者节点来完成;
选取slave节点作为master节点的具体过程:
1.选择slave-priority(slave节点优先级)最高的slave节点,如果存在则返回,不存在则继续 2.选择复制偏移量(offset)最大的slave节点,offset最大说明对master的数据复制的最完整,如果存在则返回,不存在则继续 3.选择run_id最小的slave节点,run_id最小说明slave节点启动最早
jedis客户端使用redis Sentinel
JedisSentinel sentinelPool = new JedisSentinelPool(masterName,sentinelSet,poolConfig,timeout); Jedis jedis = null; try{ jedis = redisSentinelPool.getResource(); }catch(Exception e){ }finally{ if(jedis!=null) jedis.close(); }
public class RedisSentinelClient { private static JedisSentinelPool pool = null; private static String redisHosts = "127.0.0.1:26378;127.0.0.1:26379;127.0.0.1:26380"; private static String redisMaster = "";//master name private static String password = "";//密码,可选 private static final int MAX_IDLE = 200;//最大空闲数 private static final int MAX_TOTAL = 400;//最大连接数 private static final int MIN_IDLE = 200;//最小空闲数 static { //redis 连接池配置 GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig(); poolConfig.setMaxIdle(MAX_IDLE); poolConfig.setMaxTotal(MAX_TOTAL); poolConfig.setMinIdle(MIN_IDLE); poolConfig.setTestOnBorrow(true); poolConfig.setTestOnReturn(true); Set<String> hosts = new HashSet<String>(Arrays.asList(redisHosts.split(";"))); if (StringUtils.isBlank(password)) { pool = new JedisSentinelPool(redisMaster, hosts, poolConfig); } else { pool = new JedisSentinelPool(redisMaster, hosts, poolConfig, password); } } public String get(String key) throws JedisConnectionException { Jedis jedis = pool.getResource(); try { return jedis.get(key); } catch (JedisConnectionException e) { throw e; } finally { jedis.close(); } } }
本文来自博客园,作者:LeeJuly,转载请注明原文链接:https://www.cnblogs.com/peterleee/p/10781037.html
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号