Jedis, Cannot get jedis connection: cannot get res

2019-02-13 14:31发布

问题:

I have seen answers in couple of threads but didn't work out for me and since my problem occurs occasionally, asking this question if any one has any idea.

I am using jedis version 2.8.0, Spring Data redis version 1.7.5. and redis server version 2.8.4 for our caching application.

I have multiple cache that gets saved in redis and get request is done from redis. I am using spring data redis APIs to save and get data.

All save and get works fine, but getting below exception occasionally:

Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool | org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the poolorg.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:198)
org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:345)
org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:129)
org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:92)
org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:79)
org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:191)
org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:166)
org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:88)
org.springframework.data.redis.core.DefaultHashOperations.get(DefaultHashOperations.java:49)

My redis configuration class:

@Configuration
public class RedisConfiguration {

@Value("${redisCentralCachingURL}")
private String redisHost;

@Value("${redisCentralCachingPort}")
private int redisPort;

@Bean
public StringRedisSerializer stringRedisSerializer() {
  StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
  return stringRedisSerializer;
}

@Bean
JedisConnectionFactory jedisConnectionFactory() {
  JedisConnectionFactory factory = new JedisConnectionFactory();
  factory.setHostName(redisHost);
  factory.setPort(redisPort);
  factory.setUsePool(true);
  return factory;
}

@Bean
public RedisTemplate<String, Object> redisTemplate() {
  RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
  redisTemplate.setConnectionFactory(jedisConnectionFactory());
  redisTemplate.setExposeConnection(true);
  // No serializer required all serialization done during impl
  redisTemplate.setKeySerializer(stringRedisSerializer());
  //`redisTemplate.setHashKeySerializer(stringRedisSerializer());
  redisTemplate.setHashValueSerializer(new GenericSnappyRedisSerializer());
  redisTemplate.afterPropertiesSet();
  return redisTemplate;
}

@Bean
public RedisCacheManager cacheManager() {
  RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate());
  redisCacheManager.setTransactionAware(true);
  redisCacheManager.setLoadRemoteCachesOnStartup(true);
  redisCacheManager.setUsePrefix(true);
  return redisCacheManager;
 }

 }

Did anyone faced this issue or have any idea on this, why might this happen?

回答1:

We were facing the same problem with RxJava, the application was running fine but after some time, no connections could be aquired from the pool anymore. After days of debugging we finally figured out what caused the problem:

redisTemplate.setEnableTransactionSupport(true)

somehow caused spring-data-redis to not release connections. We needed transaction support for MULTI / EXEC but in the end changed the implementation to get rid of this problem.

Still we don't know if this is a bug or wrong usage on our side.



回答2:

I moved from redis.template to plain jedis. Added below configuration(can be added in redis template too) for pool and don't see any exception now:

jedisPoolConfig.setMaxIdle(30);
jedisPoolConfig.setMinIdle(10);

for redis template:

jedisConnectionFactory.getPoolConfig().setMaxIdle(30);
jedisConnectionFactory.getPoolConfig()poolConfig.setMinIdle(10);

Same above config can be added in redis template too.