当前位置:网站首页>Redis入门完整教程:客户端常见异常
Redis入门完整教程:客户端常见异常
2022-07-06 19:11:00 【谷哥学术】
在客户端的使用过程中,无论是客户端使用不当还是Redis服务端出现
问题,客户端会反应出一些异常。本小节将分析一下Jedis使用过程中常见
的异常情况。
1.无法从连接池获取到连接
JedisPool中的Jedis对象个数是有限的,默认是8个。这里假设使用的默
认配置,如果有8个Jedis对象被占用,并且没有归还,此时调用者还要从
JedisPool中借用Jedis,就需要进行等待(例如设置了maxWaitMillis>0),如
果在maxWaitMillis时间内仍然无法获取到Jedis对象就会抛出如下异常:
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource
from the pool
…
Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.
java:449)
还有一种情况,就是设置了blockWhenExhausted=false,那么调用者发现
池子中没有资源时,会立即抛出异常不进行等待,下面的异常就是
blockWhenExhausted=false时的效果:
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource
from the pool
…
Caused by: java.util.NoSuchElementException: Pool exhausted
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.
java:464)
对于这个问题,需要重点讨论的是为什么连接池没有资源了,造成没有
资源的原因非常多,可能如下:
·客户端:高并发下连接池设置过小,出现供不应求,所以会出现上面
的错误,但是正常情况下只要比默认的最大连接数(8个)多一些即可,因
为正常情况下JedisPool以及Jedis的处理效率足够高。
·客户端:没有正确使用连接池,比如没有进行释放,例如下面代码所
示。
定义JedisPool,使用默认的连接池配置:
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
JedisPool jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379);
像JedisPool借用8次连接,但是没有执行归还操作:
for (int i = 0; i < 8; i++) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.ping();
} catch (Exception e) {
e.printStackTrace();
}
}
当调用者再向连接池借用Jedis时(如下操作),就会抛出异常:
jedisPool.getResource().ping();
·客户端:存在慢查询操作,这些慢查询持有的Jedis对象归还速度会比
较慢,造成池子满了。
·服务端:客户端是正常的,但是Redis服务端由于一些原因造成了客户
端命令执行过程的阻塞,也会使得客户端抛出这种异常。
可以看到造成这个异常的原因是多个方面的,不要被异常的表象所迷
惑,而且并不存在万能钥匙解决所有问题,开发和运维只能不断加强对于
Redis的理解,顺藤摸瓜逐渐找到问题所在。
2.客户端读写超时
Jedis在调用Redis时,如果出现了读写超时后,会出现下面的异常:
redis.clients.jedis.exceptions.JedisConnectionException:
java.net.SocketTimeoutException: Read timed out
造成该异常的原因也有以下几种:
·读写超时间设置得过短。
·命令本身就比较慢。
·客户端与服务端网络不正常。
·Redis自身发生阻塞。
3.客户端连接超时
Jedis在调用Redis时,如果出现了连接超时后,会出现下面的异常:
redis.clients.jedis.exceptions.JedisConnectionException:
java.net.SocketTimeoutException: connect timed out
造成该异常的原因也有以下几种:
1)连接超时设置得过短,可以通过下面代码进行设置:
// 毫秒
jedis.getClient().setConnectionTimeout(time);
2)Redis发生阻塞,造成tcp-backlog已满,造成新的连接失败。
3)客户端与服务端网络不正常。
4.客户端缓冲区异常
Jedis在调用Redis时,如果出现客户端数据流异常,会出现下面的异
常:
redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.
造成这个异常的原因可能有如下几种:
1)输出缓冲区满。例如将普通客户端的输出缓冲区设置为1M1M60:
config set client-output-buffer-limit "normal 1048576 1048576 60 slave 268435456
67108864 60 pubsub 33554432 8388608 60"
如果使用get命令获取一个bigkey(例如3M),就会出现这个异常。
2)长时间闲置连接被服务端主动断开,上节已经详细分析了这个问
题。
3)不正常并发读写:Jedis对象同时被多个线程并发操作,可能会出现
上述异常。
5.Lua脚本正在执行
如果Redis当前正在执行Lua脚本,并且超过了lua-time-limit,此时Jedis
调用Redis时,会收到下面的异常。对于如何处理这类问题,在第3章Lua的
小节已经进行了介绍,这里就不再赘述。
redis.clients.jedis.exceptions.JedisDataException: BUSY Redis is busy running a
script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.
6.Redis正在加载持久化文件
Jedis调用Redis时,如果Redis正在加载持久化文件,那么会收到下面的
异常:
redis.clients.jedis.exceptions.JedisDataException: LOADING Redis is loading the
dataset in memory
7.Redis使用的内存超过maxmemory配置
Jedis执行写操作时,如果Redis的使用内存大于maxmemory的设置,会
收到下面的异常,此时应该调整maxmemory并找到造成内存增长的原因:
redis.clients.jedis.exceptions.JedisDataException: OOM command not allowed when
used memory > 'maxmemory'.
8.客户端连接数过大
如果客户端连接数超过了maxclients,新申请的连接就会出现如下异
常:
redis.clients.jedis.exceptions.JedisDataException: ERR max number of clients reached
此时新的客户端连接执行任何命令,返回结果都是如下:
127.0.0.1:6379> get hello
(error) ERR max number of clients reached
这个问题可能会比较棘手,因为此时无法执行Redis命令进行问题修
复,一般来说可以从两个方面进行着手解决:
·客户端:如果maxclients参数不是很小的话,应用方的客户端连接数基
本不会超过maxclients,通常来看是由于应用方对于Redis客户端使用不当造
成的。此时如果应用方是分布式结构的话,可以通过下线部分应用节点(例
如占用连接较多的节点),使得Redis的连接数先降下来。从而让绝大部分
节点可以正常运行,此时再通过查找程序bug或者调整maxclients进行问题的
修复。
·服务端:如果此时客户端无法处理,而当前Redis为高可用模式(例如
Redis Sentinel和Redis Cluster),可以考虑将当前Redis做故障转移。
此问题不存在确定的解决方式,但是无论从哪个方面进行处理,故障的
快速恢复极为重要,当然更为重要的是找到问题的所在,否则一段时间后客
户端连接数依然会超过maxclients。
边栏推荐
猜你喜欢
Digital scrolling increases effect
Derivative, partial derivative, directional derivative
Pioneer of Web3: virtual human
Statistics of radar data in nuscenes data set
Detailed explanation of line segment tree (including tested code implementation)
MES管理系统的应用和好处有哪些
What are the applications and benefits of MES management system
Summer Challenge database Xueba notes (Part 2)~
导数、偏导数、方向导数
What are the characteristics of the operation and maintenance management system
随机推荐
人脸识别应用解析
leetcode:5. Longest palindrome substring [DP + holding the tail of timeout]
C # / vb. Net supprime le filigrane d'un document word
wireshark安装
Station B's June ranking list - feigua data up main growth ranking list (BiliBili platform) is released!
STM32 project -- Topic sharing (part)
Douban average 9 x. Five God books in the distributed field!
How to write test cases for test coupons?
CDB PDB user rights management
Argo workflows source code analysis
Kysl Haikang camera 8247 H9 ISAPI test
Web3的先锋兵:虚拟人
NuScenes数据集关于Radar数据的统计
Lombok makes the pit of ⽤ @data and @builder at the same time
widerperson数据集转化为YOLO格式
The annual salary of general test is 15W, and the annual salary of test and development is 30w+. What is the difference between the two?
Contribution of Writing Series
4 -- Xintang nuc980 mount initramfs NFS file system
MetaForce原力元宇宙佛萨奇2.0智能合约系统开发(源码部署)
How to design interface test cases? Teach you a few tips to draft easily