07-Redis Sentinel

nobility 发布于 2022-11-06 191 次阅读


Redis Sentinel

架构

Redis-sentinel架构

原理

三个定时任务

  1. 每十秒每个哨兵节点对所有已知的Redis节点执行info操作
    • 作用:确认当前节点之间的关系,发现新节点,所以配置文件中只需要配置监控主节点,就能监控所有节点
  2. 每两秒每个哨兵节点通过主节点的__sentinel__:hello频道交换信息
    • 作用:用于不同哨兵之间的通信与感知,所以配置文件中只需要配置监控的主节点,各个哨兵之间就能互相监控
  3. 每一秒每个哨兵节点对其他哨兵节点和Redis节点执行ping,也就是心跳检测
    • 作用:判断是否存活的依据

主观下线与客观下线

  • 主观下线:单个哨兵对Redis节点是否在线的看法
  • 客观下线:所有哨兵对Redis节点是否在线的看法
    • 将自己的认为的主观下线,使用sentinel is-master-down-by-addr命令告知其他哨兵自己认为的那个Redis节点主观下线
    • 当超过一定票数,则认为该Redis节点离线,所以哨兵个数应该是大于等于3的奇数个,配置的票数一个是一半以上比较好

领导者选举

原因:对于故障转移操作,只需要一个哨兵操作即可

选举: sentinel is-master-down-by-addr命令不仅是告知主观下线,同时也告知其他哨兵希望成为领导者

  1. 每个做主观下线的哨兵节点向其他哨兵节点发送命令,要求将自己设置为领导者
  2. 收到命令的哨兵节点如果没有同意其他哨兵节点,那么将同意该请求,否则拒绝
  3. 如果该哨兵节点发现自己的票数已经超过哨兵集合半数并且超过quorum,那么就会成为领导者
  4. 如果此过程有多个哨兵节点成为了领导者,则等待一段时间重新进行选举

故障转移具体操作

  1. 领导者从从节点中选出一个合适的节点作为新的主节点
    • 选择优先级最高的从节点,可通过slave-priority配置项进行配置,若优先级相同接着向下
    • 选择复制偏移量最大的从节点,即复制的最完整的,若偏移量相同接着向下
    • 选择runId最小的从节点,即启动最早的节点
  2. 对选中的节点执行slave no one命令让其成为master节点
  3. 向其余未选中节点发送命令,让他们成为新主节点的从节点,进行同步,复制规则根据具体配置而定
  4. 更新对原来主节点配置为从节点,并持续进行监控,当其恢复后命令它去同步新的主节点

实现方式

服务端

启动哨兵服务器需要使用redis-sentinel指定配置文件来启动,由此可见,redis的一下配置项也可以用作redis-sentinel

其中sentinel前缀的配置项中都需要指定master-name,也就是主从复制架构中的主节点名称,从而达到可监控多套架构的目的,可以自定义取名,默认名称是mymaster

配置项 描述 默认值
port sentinel的端口号 26379
dir sentinel的工作目录
logfile sentinel的日志文件
daemonize 是否以后台守护进程启动
sentinel monitor 监控的主节点IP和端口,满足客观下线的票数 127.0.0.1 6379 2
sentinel auth-pass 监控节点密码
sentinel down-after-milliseconds 无响应超时时间,超过此时间无响应就会认为该节点主观下线,单位毫秒 30000
sentinel parallel-syncs mymaster 在故障转移时的复制规则,即可同时进行复制的节点个数 1
sentinel failover-timeout 故障转移的超时时间 180000

客户端

  1. 客户端需要知道所有哨兵节点和要访问master-name,因为客户端不知道那个哨兵是活的,所以需要遍历从中选取一个可用的即可,再通过master-name来告知哨兵要访问的是那一套主从复制的架构
  2. 向哨兵发送sentinel get-master-addr-by-name masterName命令, 该哨兵就会返回真正的主节点IP和端口
  3. 客户端连接该主节点,发送role或者role replication命令,进行确认,确认该节点真的主节点
  4. 如果主节点发生故障转移,哨兵是能够感知,并通过发布订阅模型将最新的主节点信息告知客户端

Jedis已经封装好了,直接使用即可,仅仅只是连接池变成了哨兵连接池

JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); //若不进行配置,则使用的是默认配置
//1. 创建连接池配置对象,进行配置
Set<String> sentinelSet = new HashSet<String>();  //添加多个哨兵的地址
sentinelSet.add("127.0.0.1:26379");
sentinelSet.add("127.0.0.1:26380");
sentinelSet.add("127.0.0.1:26381");
JedisSentinelPool sentinelPool = new JedisSentinelPool("myMaster", sentinelSet, jedisPoolConfig);
//2. 根据配置对象创建哨兵连接池对象
Jedis jedis = null;
try {
  jedis = sentinelPool.getResource();
  //3. 从连接池中借用Jedis对象
  jedis.auth("redis");  //操作数据前设置的密码
  String hello = jedis.get("hello");
  System.out.println(hello);  //world
  //4. 通过Jedis执行命令,返回Jedis执行结果
} catch (Exception e) {
  System.out.println("发生故障");
} finally {
  if (jedis != null) {
    jedis.close();
    //5. 归还Jedis连接
  }
}

节点运维

节点下线

  • 哨兵节点:直接关闭即可,其他哨兵节点会自动感知到
  • 从节点:直接关闭即可,哨兵节点会自动感知到
  • 主节点:选择一个哨兵节点,连接后执行sentinel failover命令指定下线的主节点名,该哨兵就会成为领导者进行故障转移操作

节点上线

  • 哨兵节点:参考其他哨兵节点启动即可,其他哨兵节点会自动感知到
  • 从节点:设置主节点启动即可,哨兵节点会自动感知到
  • 主节点:选择一个从节点,连接后执行config set slave-priority 指定较高的优先级,再选择一个哨兵节点连接执行sentinel failover命令指定下线的主节点名,该哨兵就会成为领导者进行故障转移操作
此作者没有提供个人介绍
最后更新于 2022-11-06