Jedis连接池的使用

时间:2023-02-09 17:30:06
为什么要使用Jedis连接池

Redis作为缓存数据库理论上和MySQL一样需要客户端和服务端建立起来连接进行相关操作,使用MySQL的时候相信大家都会使用一款开源的连接池,例如C3P0.因为直连会消耗大量的数据库资源,每一次新建一个连接之,使用后再断开连接,对于频繁访问的场景,这显然不是高效的。

Jedis连接池的使用

Jedis直连Redis

生产环境一般使用连接池的方式对Redis连接进行管理,所有Jedis对象先放在池子中每一次需要的时候连接Redis,只需要在池子中借,用完了再归还给池子。

Jedis连接池的使用

Jedis连接池使用方式

客户端连接Redis使用的是TCP协议,直连的方式每次需要建立TCP连接,而连接池的方式是可以预先初始化好Jedis连接,所以每次只需要从Jedis连接池借用即可,而借用和归还操作是在本地进行的,只有少量的并发同步开销,远远小于新建TCP连接的开销。另外直连的方式无法限制Jedis对象的个数,在极端情况下可能会造成连接泄露,而连接池的形式可以有效的保护和控制资源的使用。但是直连的方式也并不是一无是处,下面给出两种方式各自的优劣势。

Jedis连接池的使用

Jedis直连方式和连接池方式对比

Jedis提供了JedisPool这个类作为对Jedis的连接池,同时使用了Apache的通用对象池工具common-pool作为资源的管理工具,下面是使用JedisPool操作Redis的代码示例:

1.Jedis连接池(通常JedisPool是单例的):

GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();

JedisPool jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379);

2.获取Jedis对象不再是直接生成一个Jedis对象,而是直接从连接池里获取,示例代码如下:

Jedis jedis = null;

try {

// 1. 从连接池获取 jedis 对象

jedis = jedisPool.getResource();

// 2. 执行操作

jedis.get("hello");

} catch (Exception e) {

logger.error(e.getMessage(),e);

} finally {

if (jedis != null) {

// 如果使用 JedisPool , close 操作不是关闭连接,代表归还连接池

jedis.close();

}

}

这里可以看到在finally中依然是jedis.close()操作,为什么会把连接关闭呢,这不和连接池的原则违背了吗?但实际上Jedis的close()实现方式如下:

public void close() {

// 使用 Jedis 连接池

if (dataSource != null) {

if (client.isBroken()) {

this.dataSource.returnBrokenResource(this);

} else {

this.dataSource.returnResource(this);

}

// 直连

} else {

client.close();

}

}

参数说明

dataSource!=null代表使用的是连接池,所以jedis.close()代表归还

连接给连接池,而且Jedis会判断当前连接是否已经断开。

dataSource=null代表直连,jedis.close()代表关闭连接。

前面GenericObjectPoolConfig使用的是默认配置,实际它提供有很多参数,例如池子中最大连接数、最大空闲连接数、最小空闲连接数、连接活性检测,等等,例如下面代码:

GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();

// 设置最大连接数为默认值的 5 倍

poolConfig.setMaxTotal(GenericObjectPoolConfig.DEFAULT_MAX_TOTAL * 5);

// 设置最大空闲连接数为默认值的 3 倍

poolConfig.setMaxIdle(GenericObjectPoolConfig.DEFAULT_MAX_IDLE * 3);

// 设置最小空闲连接数为默认值的 2 倍

poolConfig.setMinIdle(GenericObjectPoolConfig.DEFAULT_MIN_IDLE * 2);

// 设置开启 jmx 功能

poolConfig.setJmxEnabled(true);

// 设置连接池没有连接后客户端的最大等待时间 ( 单位为毫秒 )

poolConfig.setMaxWaitMillis(3000);

上面几个是GenericObjectPoolConfig几个比较常用的属性