jredis的单机、sentinel、cluster的使用

25 篇文章 4 订阅

maven

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.5.0</version>
</dependency>

1、单机:

public class RedisUtils {
	private static Logger logger = LoggerFactory.getLogger(RedisUtils.class);

	private JedisPool pool = null;
    static {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(2000);
        config.setMaxIdle(200);
        config.setMaxWaitMillis(1000 * 3);
        config.setTestOnBorrow(true);
        config.setTestOnReturn(true);
        config.setTestWhileIdle(true);
        config.setTimeBetweenEvictionRunsMillis(1000 * 120);
        
        pool = new JedisPool(config, host, Integer.valueOf(port),1000 * 60,pwd);
    }

	public static String get(String key) {
		String value = null;
		Jedis jedis = null;
		try {
			jedis = pool.getResource();
			value = jedis.get(key);
		} catch (Exception e) {
			logger.error("RedisUtils.get first fail, key=" + key, e);
			try {
				value = jedis.get(key);
			} catch (Exception e1) {
				success = false;
				logger.error("RedisUtils.get second fail, key=" + key, e1);
			}
		} finally {
			recycleJedis(pool, jedis, success);
		}
		return value;
	}
...
	
	private static void recycleJedis(JedisPool pool, Jedis jedis, boolean success) {
    	if (success) {
    		try {
    			pool.returnResource(jedis);
    		} catch (Exception e) {}
    	} else {
    		try {
    			pool.returnBrokenResource(jedis);
    		} catch (Exception e) {}
    	}
    }
}

2、cluster版:

public class RedisUtils {
	private static Logger logger = LoggerFactory.getLogger(RedisUtils.class);
	private static JedisCluster cluster = null;
    static {
    	JedisPoolConfig poolConfig = new JedisPoolConfig();
    	// 最大连接数
    	poolConfig.setMaxTotal(300);
    	// 最大空闲数
    	poolConfig.setMaxIdle(30);
    	// 最大允许等待时间,如果超过这个时间还未获取到连接,则会报JedisException异常:
    	// Could not get a resource from the pool
    	poolConfig.setMaxWaitMillis(1000);
    	Set<HostAndPort> nodes = new LinkedHashSet<HostAndPort>();
    	nodes.add(new HostAndPort("130.349.57.218", 1738));
    	nodes.add(new HostAndPort("130.349.57.221", 1738));
    	nodes.add(new HostAndPort("130.349.57.209", 1738));
    	nodes.add(new HostAndPort("130.349.57.187", 1738));
    	nodes.add(new HostAndPort("130.349.57.220", 1738));
    	nodes.add(new HostAndPort("130.349.57.201", 1738));
    	nodes.add(new HostAndPort("130.349.57.202", 1738));
    	nodes.add(new HostAndPort("130.349.57.203", 1738));
    	cluster = new JedisCluster(nodes, poolConfig);
    }

	public static String get(String key) {
		String value = null;
		try {
			value = cluster.get(key);
		} catch (Exception e) {
			logger.error("RedisUtils.get fail, key={}",key, e);
		} 
		return value;
	}

	
	public static void closeCluster() {
		try {
			cluster.close();
		} catch (IOException e) {
			logger.error("close cluster is error...",e);
		}
	}
	
	
	public static void main(String...strings) {
		System.out.println(RedisUtils.get("o_1548664656920213070643316836998AADCE0D3C73902FBCCC1475D"));
	}
}

注:使用cluster版本时,不需要JedisCluster.close(),否则会报如下错误

redis.clients.jedis.exceptions.JedisNoReachableClusterNodeException: No reachable node in cluster
    at redis.clients.jedis.JedisSlotBasedConnectionHandler.getConnection(JedisSlotBasedConnectionHandler.java:57)
    at redis.clients.jedis.JedisSlotBasedConnectionHandler.getConnectionFromSlot(JedisSlotBasedConnectionHandler.java:74)
    at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:116)
    at redis.clients.jedis.JedisClusterCommand.run(JedisClusterCommand.java:31)
    at redis.clients.jedis.JedisCluster.get(JedisCluster.java:124)
    at cn.tbnb1.service.redis.RedisCacheService.get(RedisCacheService.java:55)
    at cn.tbnb1.seckil.controller.SeckillController.resultQuery(SeckillController.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)

原因:我们使用的是redis3.0的集群,用jedis的JedisCluster.close()方法造成的集群连接关闭的情况。 jedisCluster内部使用了池化技术,每次使用完毕都会自动释放Jedis因此不需要关闭。如果调用close方法后再调用jedisCluster的api进行操作时就会出现如上错误。

3、sentinel版本:

public class RedisSentinelClient {
    private static JedisSentinelPool pool = null;
    private static String redisHosts = "127.0.0.1:26378;127.0.0.1:26379;127.0.0.1:26380";
    private static String redisMaster = "";//master name
    private static String password = "";//密码,可选
    private static final int MAX_IDLE = 200;//最大空闲数
    private static final int MAX_TOTAL = 400;//最大连接数
    private static final int MIN_IDLE = 200;//最小空闲数
 
    static {
        //redis 连接池配置
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxIdle(MAX_IDLE);
        poolConfig.setMaxTotal(MAX_TOTAL);
        poolConfig.setMinIdle(MIN_IDLE);
        poolConfig.setTestOnBorrow(true);
        poolConfig.setTestOnReturn(true);
        Set<String> hosts = new HashSet<String>(Arrays.asList(redisHosts.split(";")));
        if (StringUtils.isBlank(password)) {
            pool = new JedisSentinelPool(redisMaster, hosts, poolConfig);
        } else {
            pool = new JedisSentinelPool(redisMaster, hosts, poolConfig, password);
        }
    }
 
    public String get(String key) throws JedisConnectionException {
        Jedis jedis = pool.getResource();
        try {
            return jedis.get(key);
        } catch (JedisConnectionException e) {
            throw e;
        } finally {
            jedis.close();
        }
    }
}

在生产环境中一定要配置GenericObjectPoolConfig中的 maxIdle、maxTotal、minIdle.因为里面默认值太低了,如果生产环境中流量比较大的话,就会出现等待redis的连接的情况。为了更好的使用redis 连接池,建议采用 JedisPoolConfig来替代GenericObjectPoolConfig。JedisPoolConfig里面有一些默认的参数。

当然,jedis中还包括了sharding功能(redis cluster未出现之前,多采用这种sharding方式组件集群,内部原理是通过一致性hash实现),具体使用见:

https://blog.csdn.net/liuxiao723846/article/details/86744772

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赶路人儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值