当前位置:网站首页>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。
边栏推荐
- Detailed explanation of line segment tree (including tested code implementation)
- 安全巡检的工作
- A new path for enterprise mid Platform Construction -- low code platform
- MySQL
- 运维管理系统有哪些特色
- Leetcode:minimum_depth_of_binary_tree解决问题的方法
- Apifox,你的API接口文档卷成这样了吗?
- Read fast RCNN in one article
- Statistics of radar data in nuscenes data set
- C#/VB. Net to delete watermarks in word documents
猜你喜欢

Kysl Haikang camera 8247 H9 ISAPI test

C#/VB.NET 删除Word文檔中的水印

数字滚动增加效果

Douban average 9 x. Five God books in the distributed field!

一文读懂Faster RCNN

postgresql之整體查詢大致過程

Increase 900w+ playback in 1 month! Summarize 2 new trends of top flow qiafan in station B

MES管理系统的应用和好处有哪些

Web3's need for law

This week's hot open source project!
随机推荐
差异与阵列和阵列结构和链表的区别
Rethinking of investment
wzoi 1~200
如何设计好接口测试用例?教你几个小技巧,轻松稿定
unity中跟随鼠标浮动的面板,并可以自适应文字内容的大小
1 -- Xintang nuc980 nuc980 porting uboot, starting from external mx25l
Integerset of PostgreSQL
[software test] the most complete interview questions and answers. I'm familiar with the full text. If I don't win the offer, I'll lose
LeetCode 77:组合
MySQL提升大量数据查询效率的优化神器
Software testing -- common assertions of JMeter interface testing
安全交付工程师
Pgadmin4 of PostgreSQL graphical interface tool
How to design interface test cases? Teach you a few tips to draft easily
[leetcode]Search for a Range
Introduction to the internal structure of the data directory of PostgreSQL
Summary of basic debugging steps of S120 driver
The so-called consumer Internet only matches and connects industry information, and does not change the industry itself
CDB PDB user rights management
测试优惠券要怎么写测试用例?