<>前言

SpringBoot2.0默认采用 Lettuce 客户端来连接 Redis 服务
默认是不使用连接池的,只有配置 redis.lettuce.pool下的属性的时候才可以使用到redis连接池

版本说明

* spring-boot-starter-data-redis:2.5.4
* redis6.2.5
* commons-pool2:2.8.1
采用 Lettuce 使用连接池,要依赖commons-pool2
<>pom 文件相关依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>
spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>
org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency
>
<>配置文件

* 单机 spring: redis: host: 192.168.1.201 port: 6379 password: 123456 timeout:
5000ms # 连接超时时间(毫秒) lettuce: pool: max-active: 20 # 连接池最大连接数(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接 min-idle: 5 # 连接池中的最小空闲连接 max-wait: 5000ms #
连接池最大阻塞等待时间(使用负值表示没有限制)
* 集群 spring: redis: host: 192.168.1.26 port: 7001 password: 123456 timeout:
5000ms # 连接超时时间(毫秒) cluster: nodes:
192.168.1.26:7001,192.168.1.26:7002,192.168.1.26:7003,192.168.1.26:7004,192.168.1.26:7005,192.168.1.26:7006
lettuce: pool: max-active: 20 # 连接池最大连接数(使用负值表示没有限制) max-idle: 10 # 连接池中的最大空闲连接
min-idle: 5 # 连接池中的最小空闲连接 max-wait: 5000ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
<>配置过程中产生的疑惑

<>问题1: 连接池是否生效?

这里我用两种方式分别验证了一下

* 分析 RedisTempalte 源码
* 向 redis 中存个十万条数据 如果连接池生效,那存入的速度应该会更快
<>分析 RedisTempalte 源码

从 redisTemplate.opsForValue().set(key, value); 直接开始

看 execute() 方法

看 RedisConnectionFactory

没有配置连接池时

配置连接池后
可以看到 clientConfiguration 多了 poolConfig 对象里面正是配置文件配置的相关参数

<>存数据测试速度

插入 1 W 条数据
配置了连接池 :

没配连接池 :

配置了连接池执行速度快了很多,连接池确实生效了

没有配置连接池并且 timeout 太小 还很容易发生连接超时异常,会在执行中报错
Unable to connect to Redis; nested exception is
io.lettuce.core.RedisConnectionException

2 W 条数据没全部插入

<>问题2: 连接池生效的前提下, 最小空闲连接是 5 ,redis 客户端的连接数为什么还是 1 呢?

通过统计 redis 客户端的连接数发现项目启动后 redis 的连接数 + 1,如果说连接池配置生效的话,redis 的连接数
应该加连接池中的最小空闲连接数才对.

<>统计客户端连接数
lsof -i:6379 | awk -F '->' '{print $2}' | awk -F ':' '{print $1}' | awk
'{sum[$1]+=1} END {for(k in sum) print k ":" sum[k]}' | sort -n -r -k 2 -t ':'
Lettuce 和 Jedis 的都是连接Redis Server的客户端程序。Jedis在实现上是直连redis
server,多线程环境下非线程安全(即多个线程对一个连接实例操作,是线程不安全的),除非使用连接池,为每个Jedis实例增加物理连接。Lettuce基于Netty的连接实例(StatefulRedisConnection),可以在多个线程间并发访问,且线程安全,满足多线程环境下的并发访问(即多个线程公用一个连接实例,线程安全),同时它是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。

经测试发现,基于 Lettuce 连接 redis, 开始会先创建一个连接实例,当一个实例不够用了才会去创建新的连接实例直到数量达到
max-active,请求高峰过去后,会先维持最大空闲连接一段时间,之后逐渐减少至最小空闲连接

技术
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:766591547
关注微信