redis设计与实现-Sentinel

作者 : 开心源码 本文共3495个字,预计阅读时间需要9分钟 发布时间: 2022-05-13 共190人阅读

sentinel哨兵模式架构.png

概念

Sentinel只是一个运行在特殊模式下的Redis服务器,它使用了和普通模式不同的命令表,所以Sentinel模式能够使用的命令和普通Redis服务器能够使用的命令不同。用于redis主从架构环境中。

原理

  • 三个定时任务

    1. 每个Sentinel节点会向主节点和从节点发送info命令获取最新的拓扑结构
    2. Sentinel向Redis数据节点的sentinel:hello 频道发送信息,所有sentinel节点都订阅该频道,用于交换各个sentinel节点的状态,以及发现新节点。
    3. 每个sentinel向其它各个节点发送心跳检测
  • 主观下线

    当Sentinel将一个主服务器判断为主观下线时,它会向同样监视这个主服务器的其余Sentinel进行讯问,看它们能否同意这个主服务器已经进入主观下线状态。

  • 客观下线

当Sentinel收集到足够多的主观下线投票之后,它会将主服务器判断为客观下线,并发起一次针对主服务器的故障转移操作。

主观下线并不肯定下线,有可能是这台sentinel和主服务器之间存在通信故障,需要选举投票。

  • Sentinel领导者选举
  1. 所有在线的Sentinel都有被选为领头Sentinel的资格,换句话说,监视同一个主服务器的多个在线Sentinel中的任意一个都有可能成为领头Sentinel。
  2. 每次进行领头Sentinel选举之后,不管选举能否成功,所有Sentinel的配置纪元(configuration epoch)的值都会自增一次。配置纪元实际上就是一个计数器,并没有什么特别的。
  3. 在一个配置纪元里面,所有Sentinel都有一次将某个Sentinel设置为局部领头Sentinel的机会,并且局部领头一旦设置,在这个配置纪元里面就不能再更改。
  4. 每个发现主服务器进入客观下线的Sentinel都会要求其余Sentinel将自定义为局部领头Sentinel。
  5. 当一个Sentinel(源Sentinel)向另一个Sentinel(目标Sentinel)发送SENTINEL is-master-down-by-addr命令,并且命令中的runid参数不是*符号而是源Sentinel的运行ID时,这表示源Sentinel要求目标Sentinel将前者设置为后者的局部领头Sentinel。
  6. Sentinel设置局部领头Sentinel的规则是先到先得:最先向目标Sentinel发送设置要求的源Sentinel将成为目标Sentinel的局部领头Sentinel,而之后接收到的所有设置要求都会被目标Sentinel拒绝。
  7. 目标Sentinel在接收到SENTINEL is-master-down-by-addr命令之后,将向源Sentinel返回一条命令回复,回复中的leader_runid参数和leader_epoch参数分别记录了目标Sentinel的局部领头Sentinel的运行ID和配置纪元。
  8. 源Sentinel在接收到目标Sentinel返回的命令回复之后,会检查回复中leader_epoch参数的值和自己的配置纪元能否相同,假如相同的话,
    那么源Sentinel继续取出回复中的leader_runid参数,假如leader_runid参数的值和源Sentinel的运行ID一致,那么表示目标Sentinel将源Sentinel设置成了局部领头Sentinel。
  9. 假如有某个Sentinel被半数以上的Sentinel设置成了局部领头Sentinel,那么这个Sentinel成为领头Sentinel。举个例子,在一个由10个Sentinel组成的Sentinel系统里面,只需有大于等于10/2+1=6个Sentinel将某个Sentinel设置为局部领头Sentinel,那么被设置的那个Sentinel就会成为领头Sentinel。
  10. 由于领头Sentinel的产生需要半数以上Sentinel的支持,并且每个Sentinel在每个配置纪元里面只可设置一次局部领头Sentinel,所以在一个配置纪元里面,只会出现一个领头Sentinel。
  11. 假如在给定时限内,没有一个Sentinel被选举为领头Sentinel,那么各个Sentinel将在一段时间之后再次进行选举,直到选出领头Sentinel为止。
  • 故障转移。
  1. 在已下线主服务器属下的所有从服务器里面,筛选出一个从服务器,并将其转换为主服务器。
  2. 让已下线主服务器属下的所有从服务器改为复制新的主服务器。
  3. 将已下线主服务器设置为新的主服务器的从服务器,当这个旧的主服务器重新上线时,它就会成为新的主服务器的从服务器。

遇到问题汇总

  • 至少三个Sentinel在三个不同的盒子里
  • 单数个sentinel
  • 三个sentinel + 1 个master +2 个slave 最低测试环境

其它问题

  • Sentinel在用户端盒子里,什么实现?

java 访问方式

  1. 直接使用Jedis访问:
//连接池配置JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();jedisPoolConfig.setMaxTotal(100);jedisPoolConfig.setMaxIdle(20);jedisPoolConfig.setMinIdle(5);//哨兵配置列表Set<String> sentinelList = new HashSet<String>(Arrays.asList(        "127.0.0.1:16379",        "127.0.0.1:26379",        "127.0.0.1:36379"));JedisSentinelPool pool = new JedisSentinelPool("sentinelsMasterName", sentinelList, jedisPoolConfig, "password");//获取用户端Jedis jedis = pool.getResource();jedis.set("demo", "100");String demoValue = jedis.get("demo");
  1. 使用 template 实现:
RedisSentinelConfiguration configuration = new RedisSentinelConfiguration();String[] host = new String[]{        "127.0.0.1:16379",        "127.0.0.1:26379",        "127.0.0.1:36379"};for(String redisHost : host){    String[] item = redisHost.split(":");    String ip = item[0];    String port = item[1];    configuration.addSentinel(new RedisNode(ip, Integer.parseInt(port)));}configuration.setMaster("RedisMasterName");JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();jedisPoolConfig.setMaxTotal(100);jedisPoolConfig.setMaxIdle(20);jedisPoolConfig.setMinIdle(5);JedisConnectionFactory jedisConnectionFactory =    new JedisConnectionFactory(configuration, jedisPoolConfig);RedisTemplate<Object, Object> template = new RedisTemplate<>();//设置开启事务template.setEnableTransactionSupport(true);//set key serializerStringRedisSerializer stringRedisSerializer = new StringRedisSerializer();template.setKeySerializer(stringRedisSerializer);template.setHashKeySerializer(stringRedisSerializer);template.setConnectionFactory(jedisConnectionFactory());template.afterPropertiesSet();
说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » redis设计与实现-Sentinel

发表回复