JedisPool resource pool optimization

更新时间:
复制 MD 格式

JedisPool is a connection pool for the Jedis client. Properly configured pool parameters improve Redis performance and resource utilization. This topic covers JedisPool usage, parameter descriptions, and optimization recommendations.

Usage

This example uses Jedis 2.9.0. Maven dependency:

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

Jedis uses Apache Commons-pool2 for pool management. The key parameter class is GenericObjectPoolConfig:

GenericObjectPoolConfig jedisPoolConfig = new GenericObjectPoolConfig();
jedisPoolConfig.setMaxTotal(...);
jedisPoolConfig.setMaxIdle(...);
jedisPoolConfig.setMinIdle(...);
jedisPoolConfig.setMaxWaitMillis(...);
...

Initialize a JedisPool:

// redisHost is the IP address of the instance. redisPort is the port of the instance. redisPassword is the password of the instance. timeout is both the connection timeout and the read/write timeout.
JedisPool jedisPool = new JedisPool(jedisPoolConfig, redisHost, redisPort, timeout, redisPassword);
// Execute commands as follows.
Jedis jedis = null;
try {
    jedis = jedisPool.getResource();
    // Specific commands.
    jedis.executeCommand()
} catch (Exception e) {
    logger.error(e.getMessage(), e);
} finally {
    // In JedisPool mode, the Jedis object is returned to the resource pool.
    if (jedis != null) 
        jedis.close();
}

Parameters

JedisPool manages Jedis connections in a thread-safe, bounded pool. A proper GenericObjectPoolConfig configuration improves Redis performance and reduces resource overhead. The following tables describe key parameters and recommended settings.

Table 1. Parameters related to resource settings and usage

Parameter

Description

Default value

Recommendation

maxTotal

Maximum number of connections in the pool.

8

Recommended settings for key parameters.

maxIdle

Maximum number of idle connections in the pool.

8

Recommended settings for key parameters.

minIdle

Minimum number of idle connections maintained in the pool.

0

Recommended settings for key parameters.

blockWhenExhausted

Whether the caller blocks when the pool is exhausted. maxWaitMillis takes effect only when this is true.

true

Use the default value.

maxWaitMillis

Maximum wait time (ms) when the pool is exhausted.

-1 (never times out)

Do not use the default value.

testOnBorrow

Whether to validate connections (ping) when borrowing from the pool. Invalid connections are removed.

false

For high traffic, set to false to reduce ping overhead.

testOnReturn

Whether to validate connections (ping) when returning to the pool. Invalid connections are removed.

false

For high traffic, set to false to reduce ping overhead.

jmxEnabled

Whether to enable JMX monitoring.

true

Enable this. Ensure it is also enabled for your application.

The following four parameters control idle connection detection.

Table 2. Parameters related to idle resource detection

Name

Description

Default value

Recommendation

testWhileIdle

Whether to validate idle connections (ping) during eviction runs. Invalid connections are destroyed.

false

true

timeBetweenEvictionRunsMillis

Interval (ms) between idle connection eviction runs.

-1 (no detection)

Set this to enable detection. You can choose the period or use the JedisPoolConfig defaults below.

minEvictableIdleTimeMillis

Minimum idle time (ms) before a connection is eligible for eviction.

1,800,000 (30 minutes)

The default (30 minutes) is usually sufficient. You can also use the JedisPoolConfig defaults below.

numTestsPerEvictionRun

Number of connections tested per eviction run.

3

Tune based on your pool size. Set to -1 to check all connections per eviction run.

JedisPoolConfig extends GenericObjectPoolConfig with these idle detection defaults:

public class JedisPoolConfig extends GenericObjectPoolConfig {
  public JedisPoolConfig() {
    setTestWhileIdle(true);
    setMinEvictableIdleTimeMillis(60000);
    setTimeBetweenEvictionRunsMillis(30000);
    setNumTestsPerEvictionRun(-1);
    }
}
Note

All default values are defined in the org.apache.commons.pool2.impl.BaseObjectPoolConfig class.

Recommended settings for key parameters

maxTotal (maximum connections)

Consider the following factors when setting maxTotal:

  • Expected Redis concurrency.

  • Client-side command execution time.

  • Available Redis resources. The number of nodes (application ECS instances) multiplied by maxTotal must not exceed the maximum connections allowed for the instance. Check the instance details page for this limit.

  • Resource overhead from idle connections and frequent pool scaling.

Example: if average command time (borrow + execute + network) is 1 ms, one connection handles ~1,000 QPS. For a target of 50,000 QPS on a single instance (total QPS / number of shards), the theoretical maxTotal is 50,000 / 1,000 = 50.

Add a buffer above the theoretical value. However, oversizing maxTotal wastes client and server resources and does not help when large commands cause blocking.

maxIdle and minIdle

maxIdle represents the actual peak connections your workload needs, while maxTotal provides a buffer. Avoid setting maxIdle too low — this forces the pool to frequently create new Jedis connections. minIdle controls idle resource detection.

Best performance occurs when maxTotal equals maxIdle, which avoids pool scaling overhead. Set them equal if your workload has traffic spikes. If concurrency is low or maxIdle is too high, idle connections are wasted.

Estimate pool size per node based on total QPS and the number of client instances.

Use monitoring to obtain reasonable values

In production, use JMX or other monitoring to determine optimal values based on actual usage patterns.

FAQ

Insufficient resources

The following cases prevent obtaining a resource from the pool.

  • Timeout:

    redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
    …
    Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:449)
  • The blockWhenExhausted parameter is set to false, so the call does not wait for a resource to be released:

    redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
    …
    Caused by: java.util.NoSuchElementException: Pool exhausted
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:464)

This exception is not always caused by an insufficient pool size. It can also result from network issues, misconfigured pool parameters, JMX monitoring, missing jedis.close() calls, slow queries, or DNS problems. Recommended settings for key parameters.

Warming up JedisPool

JedisPool does not eagerly create connections on initialization. The first request triggers a new Jedis connection, which adds latency. With a small timeout, this may cause timeouts at startup. To avoid this, prefetch connections based on minIdle after pool creation:

List<Jedis> minIdleJedisList = new ArrayList<Jedis>(jedisPoolConfig.getMinIdle());

for (int i = 0; i < jedisPoolConfig.getMinIdle(); i++) {
    Jedis jedis = null;
    try {
        jedis = pool.getResource();
        minIdleJedisList.add(jedis);
        jedis.ping();
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
    } finally {
    }
}

for (int i = 0; i < jedisPoolConfig.getMinIdle(); i++) {
    Jedis jedis = null;
    try {
        jedis = minIdleJedisList.get(i);
        jedis.close();
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
    } finally {
    
    }
}

For other errors, see Common errors.