redis连接池
redis连接池的懒加载
redis初始化的时候,不会自动初始化连接,只有用到的时候,才会初始化。
连接池参数
优化建议:
1). maxTotal: 最大连接数,早期版本叫maxActive
实际上这个是一个很难回答的问题,考虑的因素比较多:
业务希望Redis并发量
客户端执行命令时间
Redis资源:例如 nodes(例如应用个数) * maxTotal 是不能超过redis的最大连接数maxClients。
资源开销:例如虽然希望控制空闲连接(连接池此刻可马上使用的连接),但是不希望因为连接池的频繁释放创建连接造成不必要开销。
以例子说明:假设
1. 一次命令时间(borrow| return resource + jedis 执行命令(含网络)) 的平均耗时约为1ms,一个连接的qps 大约是1000 (1000ms / 1ms)
业务期望的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){ } }