Redis哨兵机制

文章详细介绍了Redis分片存在的问题及解决方案,包括在节点宕机时通过3台服务器实现故障迁移和数据同步。接着,它阐述了Redis主从复制的配置步骤,确保数据实时同步。然后,讨论了哨兵的原理和配置,如何在主机宕机后自动选举新主机。最后,展示了如何在SpringBoot中整合哨兵以实现高可用性,以及在实际应用中可能出现的问题和解决策略。
摘要由CSDN通过智能技术生成

一、Redis分片存在的问题

问题说明:当使用redis分片时,如果发现redis节点宕机时,将直接影响redis分片的使用。

 解决方案:准备3redis服务器.当其中一台redis节点宕机时.则另外的服务器可以实现自动的故障迁移.

前提:得实现主从复制,内存数据的复制

二、主从复制的配置(数据同步)

由于分片机制和哨兵机制属于不同的实现逻辑.为了不产生干扰,需要将分片的配置全部关闭 

准备3台服务器.   6379主机, 6380/6381从机.

复制shards文件目录改名为sentinel.

cp -r shards sentinel

 删除sentinel目录下dump.rdb文件

rm -f dump.rdb

启动三台redis

redis-server 6379.conf

业务逻辑: 6379主机    6380/6381当从机

   如果主机的中set数据,则从机会实时同步内存数据.

   检查节点的状态    

info replication

    将6380/6381都挂载到6379

slaveof

 测试数据是否同步,检查状态信息

 

 三、Redis 哨兵的原理

   前提:redis主从搭建成功之后开始实现哨兵的高可用.

1、 哨兵会定期向主机发送心跳检测(PING-PONG),如果主机连续3次没有返回数据(PONG).哨兵断定主机宕机了.哨兵监听主机的同时,会记录主机的全部的主从状态信息

2、根据选举机制,选择新的主机

3、如果哨兵选举了新的主节点.那么其他节点将动态的修改主从的配置.充当新节点的从机

 

 编辑哨兵的配置文件

redis根目录下哨兵的配置文件sentinel.conf复制到sentinel下

cp sentinel.conf sentinel/

关闭保护模式,redis的默认条件下,保护模式开开启的.保护模式开启.程序不能远程访问

 

 开启后台启动

修改哨兵的监听

 Redis哨兵高可用测试

启动哨兵命令:

redis-sentinel sentinel.conf

   

redis主机宕机,30秒之后,检查是否有新的服务器当做主机.

将原有主机再次启动,检查服务器是否为从机!!!!

 检测原有服务器:

 

四、SpringBoot整合哨兵

编辑redis.properties配置文件

redis.sentinel=192.168.126.174:26379

编辑配置类

配置类的核心思想,整合哨兵的配置

@Configuration
@PropertySource("classpath:/properties/redis.properties")
public class RedisConfig {
    /**
     * 整合redis哨兵
     * 创建哨兵的池对象
     */
    @Value("${redis.sentinel}")
    private String redisSentinel;
    @Bean
    public JedisSentinelPool jedisSentinelPool() {
        Set<String> sentinels = new HashSet<>();
        sentinels.add(redisSentinel);
        return new JedisSentinelPool("mymaster",sentinels);
    }

    /**
     * 动态获取池中的jedis对象
     * 问题说明:如何在方法中,动态获取bean对象
     * 知识点说明:
     *  1.Spring @Bean注解工作时,如果发现方法有参数列表.则会自动的注入.
     *  2.@Qualifier利用名称,实现对象的动态赋值
     * sentinelJedis:jedis对象
     */
    @Bean
    @Scope("prototype")//设置为多例,用户什么时候使用,什么时候创建对象
    public Jedis sentinelJedis(JedisSentinelPool jedisSentinelPool) {
        //该jedis有高可用的效果.
        return jedisSentinelPool.getResource();
    }
}

编辑CacheAOP

@Component  //将对象交给spring容器管理
@Aspect     //自定义切面
public class CacheAOP {    
    @Autowired//1.按照类型进行注入    2.按照名称匹配
    @Qualifier("sentinelJedis")    //指定bean的名称进行注入
    private Jedis jedis;        //从哨兵中获取jedis
    
    @Around("@annotation(cacheFind)")
    public Object around(ProceedingJoinPoint joinPoint, CacheFind cacheFind) {
        //调用方法,获取key
        String key = getKey(joinPoint, cacheFind);
        String value = jedis.get(key);
        Object object = null;
        try {
            if (StringUtils.isEmpty(value)) {
                //缓存中没有数据,查询数据库
                object = joinPoint.proceed();
                String json = ObjectMapperUtil.toJson(object);
                //判断是否需要超时设定
                if (cacheFind.seconds() > 0) {
                    jedis.setex(key, cacheFind.seconds(), json);
                } else {
                    //该数据永不超时
                    jedis.set(key, json);
                }
                System.out.println("AOP查询数据库!!!");
            } else {
                //需要动态的获取返回值类型
                MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
                Class<?> targetClass = methodSignature.getReturnType();
                object = ObjectMapperUtil.toObject(value, targetClass);
                System.out.println("AOP查询缓存!!!");
            }
        } catch (Throwable e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        jedis.close();
        return object;
    }

    //动态获取key
    private String getKey(ProceedingJoinPoint joinPoint, CacheFind cacheFind) {
        //1.检查用户是否传递key
        String key = cacheFind.key();
        if (StringUtils.isEmpty(key)) {
            //包名.类名.方法名::第一个参数
            String className = joinPoint.getSignature().getDeclaringTypeName();
            String mothedName = joinPoint.getSignature().getName();
            Object arg0 = joinPoint.getArgs()[0];
            key = className + "." + mothedName + "::" + arg0;
        }
        return key;
    }
}

修改Service实现类

    //@Autowired
    private Jedis jedis;

报错说明

 哨兵在注入时,需要指定jedis注入的类型.否则可能会产生歧义.如上图所示.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值