问题描述:
昨天压测时发现一个问题:
在Redis 集群模式(cluster-enable、6个节点,3主3备)下,Redis的客户端程序配置了连接池并不能生效
客户端程序(这里是用的springboot)会不停创建连接,并处于TIME_WAIT状态,这表示客户端频繁向服务端发出关闭TCP连接的请求,导致大量连接处于四次握手后的TIME_WAIT状态来不及清理。换句话说,就是连接池没有生效。
最后客户端服务器总体连接数达到本地端口数上限,无法再创建新的连接,报错:Cannot assign requested address
最后通过调整客户端服务器TIME_WAIT连接数上限的临时办法解决问题,后续有机会再深入分析。
临时解决办法:
调整TIME_WAIT数量上限:
vi /etc/sysctl.conf 新增内容: net.ipv4.tcp_max_tw_buckets = 50000 sysctl -p
使用版本:
操作系统:CentOS7.4
redis版本:redis-5.0.2
依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.0.6.RELEASE</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.5.0</version> </dependency>
配置:
application.yml
spring:
redis:
cluster:
nodes: 192.168.255.101:6666,192.168.255.101:6667,192.168.255.102:6666,192.168.255.102:6667,192.168.255.103:6666,192.168.255.103:6667
max-redirects: 3
password: 123456
#连接超时时间
timeout: 200000
lettuce:
pool:
#连接池最大连接数
max-active: 200
#连接池最大阻塞等待时间
max-wait: 30
#连接池最大空闲连接
max-idle: 10
#连接池最小空闲连接
min-idle: 5
# host: 192.168.9.77
# port: 6379
server:
port: 3000
代码:
直接注入StringRedisTemplate,获取某个key,key的value需要事先在redis中set进去。具体代码略
升级版解决办法(保证连接池生效,2020年5月6日追加):
幸运的是不用亲自深入源码就能将问题解决
——将lettuce依赖改为jedis,再调整连接池的配置写法为jedis的,即可享受jedis连接池,lettuce更像是个半成品,不仅集群模式下连接池异常,pipline也支持的不好。
(个人言论,仅供参考)