文档章节

Redis客户端常见异常分析

九州暮云
 九州暮云
发布于 2017/09/12 11:28
字数 1678
阅读 91
收藏 2
点赞 0
评论 0

在Redis客户端的使用过程中,无论是客户端使用不当或者Redis服务端出现问题,客户端会反应出一些异常,下面分析一下Jedis使用过程中常见的异常情况:

一、无法从连接池获取到连接

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)

对于这个问题,需要重点讨论的是为什么连接池没有资源了,造成没有资源的可能的原因非常多

  • 1.客户端:高并发下连接池设置过小,出现供不应求,所以会出现上面的错误,但是正常情况下只要比默认的最大连接数(8个)多一些即可,因为正常情况下JedisPool以及Jedis的处理效率足够高。

  • 2.客户端:没有正确使用连接池,比如没有进行释放,例如下面代码所示: 定义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();
  • 3.客户端:存在慢查询操作,这些慢查询持有的Jedis对象归还速度会比较慢,造成池子满了。

  • 4.服务端:客户端是正常的,但是Redis服务端由于一些原因造成了客户端命令执行过程的阻塞,也会使得客户端抛出这种异常。

可以看到造成这个异常的原因是多个方面的,不要被异常的表象所迷惑,而且并不存在万能钥匙能解决所有问题,开发和运维只能不断加强对于Redis的理解,顺藤摸瓜逐渐找到问题所在。

二、 客户端读写超时

Jedis在调用Redis时,如果出现了读写超时后,会出现下面的异常:

redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out

造成该异常的原因也有以下几种:

  • 读写超时设置的过短。
  • 命令本身就比较慢。
  • 客户端与服务端网络不正常。
  • Redis自身发生阻塞。

三、客户端连接超时

Jedis在调用Redis时,如果出现了读写超时后,会出现下面的异常:

redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect timed out

造成该异常的原因也有以下几种:

  • 连接超时设置的过短。
  • Redis发生阻塞,造成tcp-backlog已满,造成新的连接失败。
  • 客户端与服务端网络不正常。

四、客户端缓冲区异常

Jedis在调用Redis时,如果出现客户端数据流异常,会出现下面的异常。

redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.

造成这个异常原因可能有如下几种:

  • 1.输出缓冲区满。例如将普通客户端的输出缓冲区设置为1M 1M 60:
config set client-output-buffer-limit "normal 1048576 1048576 60 slave 268435456 67108864 60 pubsub 33554432 8388608 60"

如果使用get命令获取一个bigkey(例如3M),就会出现这个异常。

  • 2.长时间闲置连接被服务端主动断开,可以查询timeout配置的设置以及自身连接池配置是否需要做空闲检测。

  • 3.不正常并发读写:Jedis对象同时被多个线程并发操作,可能会出现上述异常。

五、Lua脚本正在执行

如果Redis当前正在执行Lua脚本,并且超过了lua-time-limit,此时Jedis调用Redis时,会收到下面的异常。对于如何处理这类问题(Lua lua-time-limit配置之前章节已经介绍了)

redis.clients.jedis.exceptions.JedisDataException: BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.

六、Redis正在加载持久化文件

Jedis调用Redis时,如果Redis正在加载持久化文件,那么会收到下面的异常。

redis.clients.jedis.exceptions.JedisDataException: LOADING Redis is loading the dataset in memory

七、Redis使用的内存超过maxmemory配置

Jedis调用Redis执行写操作时,如果Redis的使用内存大于maxmemory的设置,会收到下面的异常,此时应该调整maxmemory并找到造成内存增长的原因(maxmemory之前章节已经介绍了)

redis.clients.jedis.exceptions.JedisDataException: OOM command not allowed when used memory > 'maxmemory'.

八、客户端连接数过大

如果客户端连接数超过了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命令,一般来说可以从两个方面进行着手。

  • 1.客户端:如果maxclients参数不是很小的话,应用方的客户端连接数基本不会超过maxclients,通常来看是由于应用方对于Redis客户端使用不当造成的。此时如果应用方是分布式结构的话,可以通过下线部分应用节点(例如占用连接较多的节点),使得Redis的连接数先降下来。从而让绝大部分节点可以正常运行,此时在再通过查找程序bug或者调整maxclients进行问题的修复。

  • 2.服务端:如果此时客户端无法处理,而当前Redis为高可用模式(例如Redis Sentinel和Redis Cluster),可以考虑将当前Redis做故障转移。

此问题不存在确定的解决方式,但是无论从哪个方面进行处理,故障的快速恢复极为重要,当然更为重要的是找到问题的所在,否则一段时间后客户端连接数依然会超过maxclients。

九、JedisCluster异常将在集群章节介绍。

附赠GenericObjectPoolConfig的重要属性

输入图片说明 输入图片说明 输入图片说明

本文部分内容来自《Redis开发与运维》一书,转载请声明。

本文转载自:https://cachecloud.github.io/2016/11/17/Redis客户端常见异常分析/

共有 人打赏支持
九州暮云
粉丝 47
博文 132
码字总数 67325
作品 0
海淀
高级程序员
Redis客户端常见异常分析

一.无法从连接池获取到连接 JedisPool中的Jedis对象个数是有限的,默认是8个。这里假设使用的默认配置,如果有8个Jedis对象被占用,并且没有归还,如果调用者还要从JedisPool中借用Jedis,就...

杀神之疯子
2017/06/02
0
0
Redis客户端常见异常分析

一.无法从连接池获取到连接 JedisPool中的Jedis对象个数是有限的,默认是8个。这里假设使用的默认配置,如果有8个Jedis对象被占用,并且没有归还,如果调用者还要从JedisPool中借用Jedis,就...

xpttxsok
2016/11/30
60
0
redis学习笔记二

http://redisbook.readthedocs.io/en/latest/ redis为什么会有高并发问题 redis的出身决定 redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘。由于单线程所以redis本身...

writeademo
2016/09/14
26
0
美团在Redis上踩过的一些坑-5.redis cluster遇到的一些问题

转载请注明出处哈:http://carlosfu.iteye.com/blog/2254154 由于演讲时间有限,有关Redis-Cluster,演讲者没做太多介绍,简单的介绍了一些Redis-Cluster概念作用和遇到的两个问题,我们在Red...

lirulei90
01/05
0
0
Redis-Cluster实战--13.redis Cluster故障转移(failover)

转载请注明出处哈:http://carlosfu.iteye.com/blog/2240426 一、测试环境 1. Redis版本: 由于我们较早的使用了Redis-Cluster版本,所以此测试使用的是Redis 3.0.0 RC1 (version 2.9.101) 后...

付磊-起扬
2015/09/29
0
0
Redis详解与常见问题解决方案

Redis简介 redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sortedset --有序集合)和hash(哈希类型)。...

-wangming-
2016/04/13
87
0
SpringBoot集成Spring Security(3)——异常处理

源码地址:https://github.com/jitwxs/blogsample 不知道你有没有注意到,当我们登陆失败时候,帮我们跳转到了,奇怪的是不管是控制台还是网页上都没有打印错误信息。 这是因为首先是默认的失...

yuanlaijike
05/09
0
0
Redis监控调研

1 调研目的 主要的目的是想调研各大云平台有关Redis监控功能的实现,但是最后我发现各大云平台提供的监控功能都比较基础,比如我想看诸如、等指标,它们都没有提供,一部分Redis监控的开源工...

yangbodong22011
2017/11/15
0
0
SegmentFault 技术周刊 Vol.37 - 分布式缓存利器:Redis

Redis 是由意大利程序员 Salvatore Sanfilippo(昵称:antirez)开发的一款内存高速缓存数据库。Redis 全称为 Remote Dictionary Server(远程数据服务),使用 C 语言编写,是一个 key-valu...

keke
2017/11/16
0
0
OSChina 技术周刊第十五期——每周技术精粹集锦

每周技术抢先看,总有你想要的! 移动开发 【软件】移动基站数据分析 SnoopSnitch 【博客】android自动连接wifi——WifiManager 【资讯】OSC 安卓客户端全面改版 —— 新界面新体验 【资讯】...

OSC编辑部
2014/12/28
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Call to undefined function Workerman\posix_getpid

workerman 在centos下报PHP Fatal error: Call to undefined function Workerman\posix_getpid posix在下面这个包中php-process...

dragon_tech
7分钟前
0
0
mysql 7.4 创建表 时  所建表 字段太多 导致失败

报错:[Err] 1118 - Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline. 解决方法:把表的引......

qimh
9分钟前
0
0
语法补漏

1.if...elif...else... 代码示例: test=10 if test>9: print(1) elif test>8: print(2) elif test>7: print(3) else: print('nothing') 输出代码: 1...

十年磨一剑3344
9分钟前
0
0
Python -re模块及正则表达式解析

传送门: https://blog.csdn.net/pipisorry/article/details/25909899 ps:上面文章中"命名分组"的语法格式不能执行。正确的如下: (?P<name>正则表达式) #name是一个合法的标识符 除了使用别名...

一口今心
17分钟前
0
0
mybatis中session.getMapper方法源码分析

0开始代码AuthorMapper mapper = session.getMapper(AuthorMapper.class); 1 DefaultSqlSession类 @Override public <T> T getMapper(Class<T> type) { //最后会去调用MapperRegistry.getMap......

writeademo
25分钟前
1
0
spring cloud zuul网关的作用

zuul一般有两大作用,1是类似于Nginx的网址重定向,但zuul的重定向的一般是整个spring cloud里在Eureka注册中心的模块. zuul: ignored-services: '*' sensitiveHeaders: routes: ...

算法之名
25分钟前
9
0
java按比例之原图生成缩略图

package com.wxp.test; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; import javax.imageio.ImageIO; import sun.......

恋码之子
35分钟前
1
0
SpringCloud 微服务 (十五) 服务容错 Hystrix

壹 工作中的微服务架构,某个服务通常会被多个服务调用或者多层调用完成需求,如果某个服务不可用,导致一个系统功能不可用或者服务直接没用了的情况,这种情况称为雪崩效应 有A服务调用B服务,B服...

___大侠
37分钟前
1
0
Spring框架中的设计模式(五)

Spring框架中的设计模式(五) 通过以前的4篇文章,我们看到Spring采用了大量的关于创建和结构方面的设计模式。本文将描述属于行为方面的两种设计模式:命令和访问者。 前传: Spring框架中的...

瑞查德-Jack
40分钟前
1
0
解决phpstorm运行很卡问题!

phpStorm一旦达到这个临界值,所有智能提示、自动补全都失效了 这TM就很尴尬了,顿时感觉自己就是个废人了,纯手写代码跟便秘一样 众所周知phpStorm基于JAVA,那么这个内存限制肯定跟JAVA的虚...

sjcehui2010
43分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部