Jedis连接池优化

Posted Natcret

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jedis连接池优化相关的知识,希望对你有一定的参考价值。

Redis的Java客户端

  • Jedis在实现上是直接连接的redis server,如果在多线程环境下是非线程安全的,这个时候只有使用连接池,为每个Jedis实例增加物理连接
  • 在SpringBoot Data Redis 1.X之前默认使用的是Jedis,但目前最新版的修改成了Lettuce。
  • 之前公司使用Jedis居多,Lettuce近两年在逐步上升,总的来讲Jedis的性能会优于Lettuce(因为它是直接操作Redis)。

第一步:导入Jedis依赖包

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

第二步:编写测试代码

public class ConnectionToRedis {

    /**
     * 连接Redis
     */
    public static void main() {
        // 创建jedis对象,连接redis服务,其中Jedis(host, port)
        Jedis jedis = new Jedis("127.0.0.1", 16379);

        // 设置认证密码,如果没有可以设置为空
        jedis.auth("root");

        // 指定数据库 默认是0
        jedis.select(1);

        // 使用ping命令,测试连接是否成功
        String result = jedis.ping();
        System.out.println(result);// 返回PONG

        // 添加一条数据
        jedis.set("username", "zhangsan");

        // 获取一条数据
        String username = jedis.get("username");
        System.out.println(username);

        // 释放资源
        if (jedis != null)
            jedis.close();
    }
}

第三步:引入连接池

我们知道Jedis是直接操作Redis,当在并发量非常大的时候,那么Jedis操作Redis的连接数很有可能就会异常,因此为了提高操作效率,引入连接池。

Jedis池化技术(JedisPool)在创建时初始化一些连接资源存储到连接池中,使用Jedis连接资源时不需要创建,而是从连接池中获取一个资源进行redis的操作,使用完毕后,不需要销毁该jedis连接资源,而是将该资源归还给连接池,供其他请求使用。

public class JedisPoolConnectRedis {

    private static JedisPool jedisPool;

    static {
        // 创建连接池配置对象
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 设置最大连接数
        jedisPoolConfig.setMaxTotal(5);
        // 设置等待时间ms(当资源池连接用尽后,调用者最大等待时间)
        jedisPoolConfig.setMaxWaitMillis(100);
        // 其中JedisPool(jedisPoolConfig, host, port, connectionTimeout, password, db)
        jedisPool = new JedisPool(jedisPoolConfig, "127.0.0.1", 6379, 100, "root", 0);
    }

    /*获取jedis*/
    public static Jedis getJedis() {
        return jedisPool.getResource();
    }


    /**
     * 连接Redis
     */
    public static void main() {
        Jedis jedis = getJedis();

        // 使用ping命令,测试连接是否成功
        String result = jedis.ping();
        System.out.println(result);// 返回PONG

        // 添加一条数据
        jedis.set("username", "zhangsan");

        // 获取一条数据
        String username = jedis.get("username");
        System.out.println(username);

        // 释放资源
        if (jedis != null)
            jedis.close();
    }
}

Jedis连接池优化

参数名:maxTotal
含义: 资源池最大连接数 【默认值:8】

使用建议: 需要考虑

  • 业务希望的Redis并发量、客户端执行命令时间
  • Redis资源:例如应用个数(客户端)* maxTotal 不能超过Redis服务端的最大连接数(config get maxclients)
  • 资源开销:例如虽然希望控制空闲连接,但是不希望因为连接池的频繁释放创建连接造成不必要的开销。

参数名:maxIdle
含义: 资源池允许最大的空闲连接数 【默认值:8】
使用建议: 建议跟maxTotal设置的值一样,这样可以减少创建新连接的开销

参数名:minIdle
含义: 资源池确保最少空闲连接数 【默认值:0】
使用建议: 建议第一次开启的时候预热(初始化一个值),减少第一次启动后的新连接开销

参数名:jmxEnabled
含义: 是否开启jmx监控,可用于监控资源使用状态 【默认值:true】
使用建议: 开启

参数名:blockWhenExhausted
含义: 当资源池用尽后,调用者是否要等待。只有当为true时,配置的maxWaitMillis参数才会生效 【默认值:true】
使用建议: 建议先使用默认值,但这个也要看情况,如果并发量大,可以直接设置false,即每次请求资源时,如果连接资源不够,马上new个新的

参数名:maxWaitMillis
含义: 当资源池连接用尽后,调用者最大等待时间(单位为毫秒) 【默认-1,表示永不超时】
使用建议: 不建议使用默认值,再高并发环境下,获取资源不能hand在一个没有超时时间的地方,具体设置根据实际场景 如设置1000即为等待1秒。

参数名:testOnBorrow、testOnReturn
含义: 这两个参数是说,客户端向连接池借用或归还时,是否会在内部进行有效性检测(ping),无效的资源将被移除 【默认值:false】
使用建议: 建议false,在高并发场景下,因为这样无形给每次增加了两次ping操作,对QPS有影响,如果不是高并发环境,可以考虑开启,或者自己来检测。

以上是关于Jedis连接池优化的主要内容,如果未能解决你的问题,请参考以下文章

Jedis连接池配置参数

Jedis的配置和优化

Jedis连接池:JedisPool及连接池工具类搭建

jedis的连接池

Jedis的使用及配置优化

jedis连接池爆满导致的服务不可用