redis连接池参数

系列文章目录

redis主从架构
redis哨兵架构
redis的集群架构
Redis的单线程和高性能
redis管道操作(节省网络IO开销)
redis的lua脚本
redis分布式锁
redis分布式锁redisson
redis缓存优化
redis的过期淘汰策略
redis连接池参数

文章目录

  • 系列文章目录
    • redis连接池
      • redis连接池的懒加载
      • 连接池参数
      • redis连接池的预热代码

redis连接池

redis连接池的懒加载

redis初始化的时候,不会自动初始化连接,只有用到的时候,才会初始化。

连接池参数

序号 参数名 含义 默认值 使用建议
1 maxTotal 资源池中最大连接数 8 设置建议见下面
2 maxIdle 资源池允许最大空闲的连接数(常驻连接) 8 设置建议见下面
3 minIdle 资源池确保最少空闲的连接数(常驻连接) 0 设置建议见下面
4 blockWhenExhausted 当资源池用尽后,调用者是否要等待。只要当为true时,下面的maxWaitMills才会生效 true 建议使用默认值
5 maxWaitMills 当连接池用尽后,调用者的最大等待时间(单位为毫秒) -1(永不超时,一直等待) 不建议使用默认值
6 testOnBorrow 向资源池借用链接时是否做连接有效性检测(ping),无效连接会被移除 false 业务量很大的时候建议设置成false(多一次ping的开销)
7 testOnReturn 向资源池归还连接是否做有效性检测(ping),无效连接会被移除 false 业务量很大的时候建议设置成false(多一次ping的开销)
8 jmxEnable 是否开起jmx监控,可用于监控 true 建议开启,但应用本身也要开启

优化建议:

1). maxTotal: 最大连接数,早期版本叫maxActive

实际上这个是一个很难回答的问题,考虑的因素比较多:

  1. 业务希望Redis并发量

  2. 客户端执行命令时间

  3. Redis资源:例如 nodes(例如应用个数) * maxTotal 是不能超过redis的最大连接数maxClients。

  4. 资源开销:例如虽然希望控制空闲连接(连接池此刻可马上使用的连接),但是不希望因为连接池的频繁释放创建连接造成不必要开销。

以例子说明:假设

​ 1. 一次命令时间(borrow| return resource + jedis 执行命令(含网络)) 的平均耗时约为1ms,一个连接的qps 大约是1000 (1000ms / 1ms)

  1. 业务期望的qps是50000

    QPS的计算公式为:QPS = 总请求数 / 总时间(秒)。

那么理论上需要的资源池大小是50000/1000=50个。但事实上这是个理论值,还要考虑到要比理论值预留一些资源,通常来讲maxTotal可以比理论值大一些。

但这个值不是越大越好,一方面连接太多占用客户端和服务端资源,另一方面对于Redis这种高QPS的服务器,一个大命令的阻塞即使设置再大资源池仍然会无济于事。

2). maxIdle和minIdle

maxldle实际上才是业务需要的最大连接数,maxTotal是为了给出余量,所以maxldle不要设置过小,否则会有new Jedis(新连接)开销。

连接池的最佳性能是maxTotal=maxldle,这样就避免连接池伸缩带来的性能干扰。但是如果并发量不大或者maxTotal设置过高,会导致不必要的连接资源浪费。一般推荐maxldle可以设置为按上面的业务期望QPS计算出来的理论连接数,maxTotal可以再放大一倍。
minldle(最小空闲连接数),与其说是最小空闲连接数,不如说是"至少需要保持的空闲连接数",在使用连接的过程中,如果连接数超过了minldle,那么继续建立连接,如果超过了maxldle,当超过的连接执行完业务后会慢慢被移出连接池释放掉。

如果系统启动完马上就会有很多的请求过来,那么可以给redis连接池做预热,比如快速的创建一些redis连接,执行简单命令,类似ping(),快速的将连接池里的空闲连接提升到minldle的数量。

redis连接池的预热代码

List<Jedis> minIdleJedisList = new ArrayList<Jedis>(jedisPoolConfig.getMinIdle())
    
for(int i = 0 ;i< jedisPoolCOnfig.getMinIdle(); i++){
    Jedis jedis = null;
    try{
        jedis = jedisPool.getResource();
        minIdleJedisList.add(jedis);
        jedis.ping();
    }catch(Exception e){
        
    }finally{
        //注意,这里不能马上close将连接还回连接池,否则最后连接池里只会建立一个连接
        //jedis.close()
    }
} 

//统一将预热的连接返还给连接池
for(int i = 0 ;i< jedisPoolCOnfig.getMinIdle(); i++){
    Jedis jedis = null;
    try{
        jedis = minIdleJedisList.get(i);
       	jedis.close();
    }catch(Exception e){
        
    }
}

你可能感兴趣的:(redis,数据库,缓存)