Redis 哨兵

Redis Sentinel是Redis高可用的实现方案,在实际生产环境中,对提高整个系统的高可用性是非常有帮助的。

当主节点发生故障时,Redis Sentinel能自动完成故障发现和故障转移,并通知客户端,从而实现高可用。

Sentinel架构

在主从的基础上增加Sentinel节点对其进行监控以及故障转移。Sentinel并不会改变原有的主从结构,只是在主从的基础上新增一个监控集群,也就是sentinel集群。一个sentinel集群可以监控多个主从集群。

故障转移步骤

  • 主节点故障,从节点失去连接
  • sentinel发现主节点故障
  • 选举处理故障的sentinel节点
  • 故障转移
    • slaveof no one
    • notice client
    • slaveof new master

环境搭建

  • 服务器规划
ip 角色
192.168.0.51 master
192.168.0.52 slave
192.168.0.53 slave
192.168.0.41 sentinel-1
192.168.0.42 sentinel-2
192.168.0.43 sentinel-3

配置说明

  • port 端口号
  • logfile 日志文件的存放目录
  • daemonize 是否以守护进程的方式运行
  • sentinel monitor master_name ip port quonum
  • sentinel down-after-milliseconds master_name times 失联的超时时间
  • sentinel parallel-syncs master_name n 并发复制的数量
  • sentinel failover-timeout master_name times 故障转移超时时间
  • sentinel auth-pass master_name passwd 主节点的密码
  • sentinel notification-script master_name script_path 故障转移期间时触发执行的脚本
  • sentinel client-reconfig-script master_name script_path 故障转移后执行的脚本

实现原理

  • 主观下线(sdown)和客观下线(odown)
  • sentinel选举
  • 故障转移的过程(master的选举)

客户端API

  • sentinel masters master_name 主节点的状态及相关信息
  • sentinel slaves master_name 从节点的状态及相关信息
  • sentinel sentinels master_name sentinel节点的集合信息
  • sentinel get-master-addr-by-name master_name 主节点的IP地址和端口
  • sentinel reset pattern 对指定主节点的配置进行重置
  • sentinel failover master_name 对指定主节点强行进行故障转移
  • sentinel ckqourum master_name 检测当前可达的sentinel节点总数是否到达quorum的个数
  • sentinel flushconfig 将sentinel节点的配置同步到磁盘上
  • sentinel remove master_name 取消对指定主节点的监控
  • sentinel monitor master_name id port quorum 监控指定主节点
  • sentinel set master_name 动态修改sentinel节点配置

Java连接Sentinel

  • 使用
package stu.redis.sentinel;

import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;

/**
 * jedis 操作哨兵
 * 
 * @author worker
 *
 */
public class RedisSentinel {

    /**
     * 主节点名字
     */
    private static final String MASTER_NAME = "mymaster";

    public static void main(String[] args) {

        Set<String> sentinels = new HashSet<>();
        sentinels.add("192.168.0.41:26379");
        sentinels.add("192.168.0.42:26379");
        sentinels.add("192.168.0.43:26379");

        JedisSentinelPool pool = new JedisSentinelPool(MASTER_NAME, sentinels);

        Jedis jedis = null;

        Scanner sc = new Scanner(System.in);

        while (true) {
            try {
                System.out.println("请输入要保存的key和value。用空格分开:");
                String inputLine = sc.nextLine(); // 阻塞

                // do something
                jedis = pool.getResource();

                String[] inputValues = inputLine.split(" ");

                jedis.set(inputValues[0], inputValues[1]);

                System.out.println(inputValues[0] + " 保存成功...");
            } finally {
                if (jedis != null) {
                    jedis.close();
                }
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/king_kgh/article/details/79112990