关于redis:Redis哨兵机制

3次阅读

共计 3331 个字符,预计需要花费 9 分钟才能阅读完成。

对于 redis 分片阐明

长处:实现内存数据的扩容。
毛病:如果 redis 分片中有一个节点呈现了问题,则整个 redis 分片机制用户拜访必然会呈现问题,间接影响用户的应用。
解决方案:实现 redis 的高可用。

配置 redis 主从构造

策略划分:1 主 2 从 6379 主 6380/6381 从
1. 将分片的目录复制 改名为 sentinel

2. 重启 redis 服务器

3. 查看 redis 节点的主从状态

4. 实现主从挂载

5. 查看主机状态

哨兵的工作原理


原理阐明:
1. 配置 redis 主从的构造。
2. 哨兵服务启动时,会监控以后的主机,同时获取主机的详情信息(主从的构造)。
3. 当哨兵刘勇心跳检测机制(PING-PANG)间断 3 次都没有收到主机的反馈信息则判定主机宕机。
4. 当哨兵发现主机宕机后,则开启选举机制,在以后的从机中筛选一台 Redis 当做主机。
5. 将其余的 redis 节点设置为新主机的从。

编辑哨兵配置文件

1. 复制配置文件
cp sentinel.conf sentinel/
2. 批改保护模式

3. 开启后盾运行

4. 设定哨兵的监控
其中的 1 示意投票失效的票数,以后只有一个哨兵所以写 1

5. 批改宕机工夫

6. 选举失败的工夫
阐明:如果选举超过指定的工夫没有完结,则从新选举

7. 启动哨兵服务

Redis 哨兵高可用实现

测试步骤:
1. 查看主机的状态
2. 将 redis 主服务器宕机期待 10 秒,之后查看从机是否入选新的主机。

3. 重启 6379 服务器,查看是否成为了新主机的从

哨兵入门案例

/**
     * 测试 Redis 哨兵
     */
    @Test
    public void testSentinel(){Set<String> set = new HashSet<>();
        //1. 传递哨兵的配置信息
        set.add("192.168.126.129:26379");
        JedisSentinelPool sentinelPool =
                new JedisSentinelPool("mymaster",set);
        Jedis jedis = sentinelPool.getResource();
        jedis.set("aa","哨兵测试");
        System.out.println(jedis.get("aa"));
    }

SpringBoot 整合 Redis 哨兵

编辑 pro 配置文件

# 配置 redis 单台服务器
redis.host=192.168.126.129
redis.port=6379

# 配置 redis 分片机制
redis.nodes=192.168.126.129:6379,192.168.126.129:6380,192.168.126.129:6381

# 配置哨兵节点
redis.sentinel=192.168.126.129:26379

编辑 redis 配置类

@Configuration
@PropertySource("classpath:/properties/redis.properties")
public class JedisConfig {@Value("${redis.sentinel}")
    private String sentinel;        // 临时只有单台

    @Bean
    public JedisSentinelPool jedisSentinelPool(){Set<String> sentinels = new HashSet<>();
        sentinels.add(sentinel);
        return new JedisSentinelPool("mymaster",sentinels);
    }
  }

批改 CacheAOP 中的注入项

package com.jt.aop;

import com.jt.anno.CacheFind;
import com.jt.config.JedisConfig;
import com.jt.util.ObjectMapperUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.ShardedJedis;

import java.lang.reflect.Method;
import java.util.Arrays;

@Aspect     // 我是一个 AOP 切面类
@Component  // 将类交给 spring 容器治理
public class CacheAOP {

    @Autowired
    //private Jedis jedis;      // 单台 redis
    //private ShardedJedis jedis; // 分片机制
    private JedisSentinelPool jedisSentinelPool;

    /**
     * 切面 = 切入点 + 告诉办法
     *        注解相干 + 盘绕告诉  控制目标办法是否执行
     *
     *  难点:
     *      1. 如何获取注解对象
     *      2. 动静生成 key  prekey + 用户参数数组
     *      3. 如何获取办法的返回值类型
     */
    @Around("@annotation(cacheFind)")  // 参数传递变量的传递
    //@Around("@annotation(com.jt.anno.CacheFind)")
    public Object around(ProceedingJoinPoint joinPoint,CacheFind cacheFind){
        // 从池中获取 jedis 对象
        Jedis jedis = jedisSentinelPool.getResource();
        Object result = null;
        try {
            //1. 拼接 redis 存储数据的 key
            Object[] args = joinPoint.getArgs();
            String key = cacheFind.preKey() +"::" + Arrays.toString(args);

            //2. 查问 redis 之后判断是否有数据
            if(jedis.exists(key)){
                //redis 中有记录, 无需执行指标办法
                String json = jedis.get(key);
                // 动静获取办法的返回值类型   向上造型  向下造型
                MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
                Class returnType = methodSignature.getReturnType();
                result = ObjectMapperUtil.toObj(json,returnType);
                System.out.println("AOP 查问 redis 缓存");
            }else{
                // 示意数据不存在, 须要查询数据库
                result = joinPoint.proceed();  // 执行指标办法及告诉
                // 将查问的后果保留到 redis 中去
                String json = ObjectMapperUtil.toJSON(result);
                // 判断数据是否须要超时工夫
                if(cacheFind.seconds()>0){jedis.setex(key,cacheFind.seconds(),json);
                }else {jedis.set(key, json);
                }
                System.out.println("aop 执行指标办法查询数据库");
            }

        } catch (Throwable throwable) {throwable.printStackTrace();
        }
        jedis.close();  // 将应用实现的链接记得敞开.
        return result;
    }

}
正文完
 0