Jedis整合单机Sentinel和Cluster模式

Posted innocent-of-dabber

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jedis整合单机Sentinel和Cluster模式相关的知识,希望对你有一定的参考价值。

配置文件和配置类

@Data
@Configuration
@ConfigurationProperties("jedis-config")
public class JedisConfigure {

    @Value("maxtotal")
    private String maxTotal;
    @Value("maxidle")
    private String maxIdle;
    @Value("minidle")
    private String minIdle;
    @Value("host")
    private String host;
    @Value("port")
    private String port;
    @Value("nodes")
    private Set<String> nodes;
    @Value("master-name")
    private String masterName;
    @Value("timeout")
    private String timeout;
}
//配置文件 放在application.yml
jedis-config:
  maxtotal: 100
  host: 127.0.0.1
  port: 6379
  maxidle: 100
  minidle: 0
  master-name: mymaster
  nodes:
    - 127.0.0.1:7001
    - 127.0.0.1:7002
    - 192.168.1.98:7003
    - 192.168.1.98:7004
    - 192.168.1.20:7005
    - 192.168.1.20:7006

  一、定义jedis接口

public interface IJedisService {

    /**
     * 获取Jedis连接
     * @return JedisCommands
     */
    JedisCommands getJedis();

    /**
     * 释放连接
     * @param jedis
     */
    void jedisClose(JedisCommands jedis);

    /**
     * 关闭连接池
     */
    void jedisPoolClose();
}

  二、定义IJedisService的实现类

@EnableConfigurationProperties(JedisConfigure.class)
public class AbstractRedisService implements IJedisService {

    Pool<Jedis> jedisPool;

    @Autowired
    private JedisConfigure jedisConfigure;

    /**
     * jedis连接池配置类
     */
    public GenericObjectPoolConfig jedisPoolConfig = new GenericObjectPoolConfig();

    /**
     * 初始化Jedis连接池配置
     */
    @PostConstruct
    public void initJedisPoolConfig() {

        jedisPoolConfig.setMaxTotal(Integer.parseInt(jedisConfigure.getMaxTotal()));
        jedisPoolConfig.setMaxIdle(Integer.parseInt(jedisConfigure.getMinIdle()));
        jedisPoolConfig.setMinIdle(Integer.parseInt(jedisConfigure.getMinIdle()));
        jedisPoolConfig.setJmxEnabled(true);
        jedisPoolConfig.setBlockWhenExhausted(true);
        jedisPoolConfig.setTestOnBorrow(true);
        jedisPoolConfig.setTestOnReturn(true);
        jedisPoolConfig.setMaxWaitMillis(-1);
    }

    /**
     *  初始化线程池
     *  根据Class类型初始化
     * @param clazz
     * @return
     */
    public void initJedisPool(Class clazz) {

        //Single
        if (JedisPool.class.getName().equals(clazz.getName()))
            jedisPool = new JedisPool(jedisPoolConfig, jedisConfigure.getHost(),
                    Integer.parseInt(jedisConfigure.getPort()), 100000);
        //Sentinel
        if (JedisSentinelPool.class.getName().equals(clazz.getName()))
            jedisPool = new JedisSentinelPool(jedisConfigure.getMasterName(),
                    jedisConfigure.getNodes(), jedisPoolConfig, 100000);

    }

    @Override
    public JedisCommands getJedis() {
        Jedis jedis = jedisPool.getResource();
        return jedis;
    }

    @Override
    public void jedisClose(JedisCommands jedis) {

        jedisPool.returnResource((Jedis) jedis);
    }

    @Override
    public void jedisPoolClose() {
        if (!jedisPool.isClosed()) jedisPool.close();
    }
}

  三、单机模式的具体实现

public class JedisSingleService extends AbstractRedisService {

    @PostConstruct
    private void loadJedisPool() {
        super.initJedisPool(JedisPool.class);
    }
}

  四、Sentinel模式的具体实现

public class JedisSentinelService extends AbstractRedisService {

    @PostConstruct
    private void loadJedisPool() {
        super.initJedisPool(JedisSentinelPool.class);
    }
}

  五、Cluster模式的具体实现

@Slf4j
@EnableConfigurationProperties(JedisConfigure.class)
public class JedisClusterService extends AbstractRedisService {

    @Autowired
    private JedisConfigure jedisConfigure;

    JedisCluster jedis;

    /**
     * 初始化配置
     */
    @PostConstruct
    private void initJedisCluster() {

        //初始化一般配置
        super.initJedisPoolConfig();

        //初始化JedisCluster
        Set<HostAndPort> clusterHostMap = Sets.newHashSet();
        initHostMap(clusterHostMap, jedisConfigure.getNodes());
        jedis = new JedisCluster(clusterHostMap, jedisPoolConfig);
    }

    /**
     * 节点转换
     *
     * @param clusterHostMap
     * @param nodes
     */
    private void initHostMap(Set<HostAndPort> clusterHostMap, Set<String> nodes) {
        if (clusterHostMap == null)
            return;
        try {
            for (String node : nodes) {

                log.info("初始化Redis-Cluster集群 --- [{}]", node);
                String[] nodeInfo = node.split(":");

                String ip = nodeInfo[0];
                Integer port = Integer.parseInt(nodeInfo[1]);

                HostAndPort hostAndPort = new HostAndPort(ip, port);
                clusterHostMap.add(hostAndPort);
            }
        } catch (Exception e) {
            throw new RuntimeException("redis-->Cluster集群节点配置异常");
        }
    }

    @Override
    public JedisCommands getJedis() {
        return jedis;
    }

    @Override
    public void jedisClose(JedisCommands jedis) {

        try {
            ((JedisCluster) jedis).close();
        } catch (IOException e) {
            e.printStackTrace();
            log.error("Redis-Cluster Close失败 --- [{}]", e.getMessage());
        }
    }
}

  六、注入Bean

@Bean
public IJedisService redisSingleJedisService() { return new JedisSingleService(); }

@Bean
IJedisService redisSentinelService() { return new JedisSentinelService(); }

@Bean
IJedisService redisClusterService() { return new JedisClusterService(); }

  

技术图片

 

以上是关于Jedis整合单机Sentinel和Cluster模式的主要内容,如果未能解决你的问题,请参考以下文章

springboot2.x版本整合redis(单机/集群)(使用lettuce)

redis单点主从集群cluster配置搭建与使用

动手实践Redis主从复制Sentinel主从切换Cluster分片

Redis Cluster 集群

非常适合新手的redis cluster搭建过程

Jedis 如何支持 Sentinel