Redis--集群-哨兵机制

为什么需要哨兵机制

  • 在上面讲到的Redis集群-主从复制模式下
  • 可以实现容灾备份和读写分离
  • 但是做不到真正的高可用
  • 如Master挂了,整个集群就只能提供读服务了, 不能够提供写服务
  • 所以需要有一个新的方案来解决这个问题
  • 这个方案就是Redis提出的哨兵机制Sentinel

哨兵机制的原理是什么

  • 如下图:
  • 在配置好了Master-Slave的基础之上,再增加一些哨兵进程
  • 用来监控各个节点(主要监控当前的Master节点)
  • 当有节点(Master)挂了,就会从该Master下属的Slave节点中选取一个作为新的Master(选取规则就不一定,很随机)
  • 注意:哨兵只做监控和选择slave作为新的master,哨兵不是备胎不会替代成为master
  • 其实哨兵本质是就是一个后台进程,不断的和redis服务做通信/心态检测
    在这里插入图片描述

如何配置哨兵机制

  • 1.三台机器修改哨兵配置文件
cd /export/servers/redis/conf

vim sentinel.conf
  • 2.node01上
#修改bind配置,每台机器修改为自己对应的主机名
bind node01  
#配置sentinel服务后台运行
daemonize yes
#修改三台机器监控的主节点,现在主节点是node01服务器
sentinel monitor mymaster node01 6379 2
#sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,node01代表监控的主服务器,6379代表端口,2代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作
# sentinel author-pass定义服务的密码,mymaster是服务名称,123456是Redis服务器密码
# sentinel auth-pass <master-name> <password>
  • 2.node02上
#修改bind配置,每台机器修改为自己对应的主机名
bind node02  
#配置sentinel服务后台运行
daemonize yes
#修改三台机器监控的主节点,现在主节点是node01服务器
sentinel monitor mymaster node01 6379 2
#sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,node01代表监控的主服务器,6379代表端口,2代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作
# sentinel author-pass定义服务的密码,mymaster是服务名称,123456是Redis服务器密码
# sentinel auth-pass <master-name> <password>
  • 3.node03上
#修改bind配置,每台机器修改为自己对应的主机名
bind node03 
#配置sentinel服务后台运行
daemonize yes
#修改三台机器监控的主节点,现在主节点是node01服务器
sentinel monitor mymaster node01 6379 2
#sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,node01代表监控的主服务器,6379代表端口,2代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作
# sentinel author-pass定义服务的密码,mymaster是服务名称,123456是Redis服务器密码
# sentinel auth-pass <master-name> <password>
  • 4.重启三台redis
/export/servers/redis/bin/redis-server /export/servers/redis/conf/redis_6379.conf
  • 5.启动三台机器上的哨兵
/export/servers/redis/bin/redis-sentinel /export/servers/redis/conf/sentinel.conf
  • 6.查看启动情况
ps -ef | grep redis
  • 7.使用客户端连接
/export/servers/redis/bin/redis-cli -h node01

/export/servers/redis/bin/redis-cli -h node02

/export/servers/redis/bin/redis-cli -h node03
  • 8.查看各自的角色
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 9.干掉node01上的master
ps -ef | grep redis

kill -9 redis-server的进程号
  • 10.过几秒观察发现node02或node03变成了master
    在这里插入图片描述
  • 11.再次启动node01的redis会发现他只能做slave了
    在这里插入图片描述

总结

  • 开发中一般都是 主从+ 哨兵 就可以满足大部分场景
  • 如果还需对redis做扩展可以再使用后面讲解的Redis集群-Cluster-终极版集群

问题

  • 之前是java代码连接的还是单机的redis
  • 那么开发中一般都是主从+ 哨兵 ,那么该如何连接呢?

JavaAPI连接主从+ 哨兵

  @Test
    public void testMasterSlaveAndSentinel(){
        //1.创建连接池配置对象
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(100);//设置最大连接
        jedisPoolConfig.setMaxIdle(10);//设置最大空闲连接数
        jedisPoolConfig.setMinIdle(5);//设置最小空闲连接数
        jedisPoolConfig.setMaxWaitMillis(2000);//最大等待时间
        jedisPoolConfig.setTestOnCreate(true);
        jedisPoolConfig.setTestOnBorrow(true);
        jedisPoolConfig.setTestOnReturn(true);
        //2.创建连接池对象
        //准备哨兵地址,注意哨兵的默认端口是26379
        Set<String> sentinels = new HashSet<>(Arrays.asList("node01:26379","node02:26379","node03:26379"));
        JedisSentinelPool jedisSentinelPool = new JedisSentinelPool("mymaster", sentinels, jedisPoolConfig);
        //3.从连接池中获取连接对象jedis
        Jedis jedis = jedisSentinelPool.getResource();
        //4.操作
        String pong = jedis.ping();
        System.out.println(pong);
        //5.归还连接
        jedis.close();
    }
  • JedisUtil也可以进行相应的修改
package cn.hanjiaxiaozhi;import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;/**
 * Author hanjiaxiaozhi
 * Date 2020/7/7 16:43
 * Desc 封装jedis工具类
 * 工具类一般都是使用类名.方法名就可以使用
 * 也就是说不需要创建对象就可以使用,那么该类最好设计成一个抽象类,因为抽象类别人不能直接new
 * 然后里面的方法设置为静态方法即可,这样别人就可以直接使用类名.方法名
 */
public abstract class JedisUtil {
    //将连接池对象提取出来,只需要在类初始化的时候创建一次即可
    private static JedisSentinelPool jedisSentinelPool;//static静态代码块只会在类被加载(第一次被使用的时候执行)
    static{
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(100);//设置最大连接
        jedisPoolConfig.setMaxIdle(10);//设置最大空闲连接数
        jedisPoolConfig.setMinIdle(5);//设置最小空闲连接数
        jedisPoolConfig.setMaxWaitMillis(2000);//最大等待时间
        jedisPoolConfig.setTestOnCreate(true);
        jedisPoolConfig.setTestOnBorrow(true);
        jedisPoolConfig.setTestOnReturn(true);
        //jedisPool = new JedisPool(jedisPoolConfig, "node01", 6379);
        Set<String> sentinels = new HashSet<>(Arrays.asList("node01:26379","node02:26379","node03:26379"));
        jedisSentinelPool = new JedisSentinelPool("mymaster", sentinels, jedisPoolConfig);}public static Jedis getJedis(){
        return jedisSentinelPool.getResource();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值