I'm currently using jedis version 2.9.0 in my maven webapp. It consists in a loop that retrieves data for caching every five minutes. For that purpose, I'm creating a jedispool on app Scheduler class when the whole app starts the execution. It runs only once on the app start and then never again.
@WebListener
public class appScheduler implements ServletContextListener {
private static JedisPool jedisPool;
private ScheduledExecutorService scheduler;
public void contextInitialized(ServletContextEvent event) {
logger.info("contextInitialized: " + event);
logger.info("Creating scheduler for cache updates...");
boolean loadStatus = PropertiesLoader.getInstance().load();
if(!loadStatus){
logger.error("Error loading properties");
System.exit(1);
}
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new UpdateCacheJob(), 1, 5, TimeUnit.MINUTES);
int port = 6379;
try {
port = Integer.parseInt(PropertiesLoader.getInstance().getCachePort());
} catch (NumberFormatException e) {
logger.error("Invalid port in properties file for cache.");
}
jedisPool = new JedisPool(PropertiesLoader.getInstance().getPoolConfig(), PropertiesLoader.getInstance().getCacheEndpoint(), port);
}
public static Jedis getJedisResource() {
return jedisPool.getResource();
}
}
My pool configuration:
final JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(128);
poolConfig.setMaxIdle(128);
poolConfig.setMinIdle(16);
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);
poolConfig.setTestWhileIdle(true);
poolConfig.setMinEvictableIdleTimeMillis(60000);
poolConfig.setTimeBetweenEvictionRunsMillis(30000);
poolConfig.setNumTestsPerEvictionRun(3);
poolConfig.setBlockWhenExhausted(true);
return poolConfig;
Every five minutes a pipeline is created to sync the new data on cache in a different class:
Jedis jedis = schedulerFunction.getJedisResource(); //retrieve resource from scheduler class
Pipeline pipeline = jedis.pipelined(); //create the pipeline
for (String key : list.keySet()) {
pipeline.setex(key, 3600, data_to_fill_cache);
}
pipeline.sync(); //sync pipeline
logger.info("Cache synched... ");
Everything works fine for many hours, but then suddenly stops with the following error:
Could not get a resource from the pool
It happens on the line of resource retrieval to create jedis on 5 minutes loop function. It doesn't happen consistently at the same time though. It could either happen after two hours or ten, it's never the same. The pipeline is following the same process every five minutes and writing the same data to redis. It's not a problem of data integrity or a sudden change that could affect the process. I've discarded any other causes. The context have been retrieved hundreds of times before suddenly getting the error.
I've been looking through all documentation on the internet but I have been unable to find a reason or a solution.
I think all your resources have been retrieved but none of them are returned.
You would have to return the resources after using them. (If you're using a good enough version of Jedis,) You can return the resource by calling jedis.close();
or try-with-resources.