`
ni_de_yang_zi
  • 浏览: 29706 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

开发中常见的redis异常总结

阅读更多

使用redis也有端时间了,现在讲开发中遇到的几个常见异常总结如下:

Redis中文官网 :http://www.redis.cn/
Redis官方推荐Java客户端Jedis(包含了所有Redis命令的实现):https://github.com/xetorthio/jedis

一、通过JedisPool类实例获取getResource()时抛出can't get a resource异常。

异常代码如下:

redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool

at redis.clients.util.Pool.getResource(Pool.java:22)

分析:

redis.clients.util.Pool.getResource会从JedisPool实例池中返回一个可用的redis连接。分析源码可知JedisPool extends redis.clients.util.Pool<Jedis> .而Pool<T>是通过

commons-pool开源工具包中的org.apache.commons.pool.impl.GenericObjectPool来实现对Jedis实例的管理的。所以我们分析一下GenericObjectPool或许能找到答案。

首先看一下common-pool的api:http://commons.apache.org/pool/apidocs/index.html?org/apache/commons/pool/impl/GenericObjectPool.html
其中三个重要个几个属性是:
MaxActive: 最大连接数。
MaxIdle: 最大空闲数。
MaxWait: 最大等待时间,单位毫秒(million seconds)。
当连接池中无可用连接时会会进行等待maxWait时间,若超出泽抛Could not get a resource from the pool异常。

所以应根据程序实际情况合理设置这三个参数的值,尽量避免这个异常。

 

二、对redis进行操作时,抛出redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out异常。

异常代码如下:

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

at redis.clients.jedis.Protocol.process(Protocol.java:79)
at redis.clients.jedis.Protocol.read(Protocol.java:131)
at redis.clients.jedis.Connection.getIntegerReply(Connection.java:188)
at redis.clients.jedis.Jedis.sismember(Jedis.java:1266)

分析:

Redis是对内存进行操作,速度应该都在毫秒级,这是我们通常的认识,

那么Redis操作怎么会出现几秒的超时时间?
我们还是先分析一下Jedis的源代码吧,以sadd操作为例:

  1. public Long sadd(final String key, final String... members) {
  2. checkIsInMulti();
  3. client.sadd(key, members);
  4. return client.getIntegerReply();
  5. }

client是redis.clients.jedis.Client.java的实例,继承关系如下:
public class Client extends BinaryClient implements Commands;

public class BinaryClient extends Connection;

Connection包装了对Redis server的socket操作,命令写操作通过socket.getOutputStream()输出流将命令信息发送到redis server,当写完命令后要通过socket.getInputStream()的到的输入流将
命令执行结果返回,这中间必然会有一个命令执行到结果返回的延时时间,这就是一个Jedis调用redis命令操作所用的时间。

需要说明的是,Redis server是单线程执行所有连接发送过来的命令的,也就是说不管并发中有多少个client在发送命令,redis-server端是单线程处理的,并按照默认的FIFO方式处理请求,

这个可在redis.conf配置文件中配置。关于redis server的详细运行机制参见:http://redis.io/documentation

所以client.sadd(key, members);调用完后只是将命令信息发送到了redis server端,具体有没有执行要看redis server的负载情况。然后,通过client.getIntegerReply();等待(time out)返回结果。
Connection初始化socket时有多种选择,其中设置socket time out 的方法如下:

  1. public void rollbackTimeout() {
  2.           try {
  3.              socket.setSoTimeout(timeout);
  4.              socket.setKeepAlive(false);
  5.           } catch (SocketException ex) {
  6.              throw new JedisException(ex);
  7.           }
  8.       }

由redis.clients.jedis.Protocol.DEFAULT_TIMEOUT = 2000 我们知道默认的超时时间是2秒,这个时间相对于redis操作内存毫秒级的速度来说已经很长,那我们为什么还会遇到
ava.net.SocketTimeoutException: Read timed out异常呢?redis操作内存虽然平均毫秒级的,但当数据量很大时未必都如此快速。在我的开发过程中就遇到过一个集合到了

千万级数据量,一次操作超时时间在秒级是很正常的,而且机器性能很好的情况下已经如此。

所以在初始化JedisPool时应该根据实际

情况通过redis.clients.jedis.JedisPoolConfig合理设置连接池参数,通过edisPool构造方法,合理设置socket读取输入InputStream的超时时间。

 

  1. pool = new JedisPool(config, host, port, 100000);

 

注意第四个参数time out,设置成我们能容忍的超时时间,单位是毫秒。

设置第四个参数后,问题基本解决。

分享到:
评论

相关推荐

    redis开发和运维

    在客户端方面,书中对Java客户端Jedis和Python客户端redis-py的使用方法进行了详细的说明,包括客户端管理、异常处理和案例分析,让开发者可以更有效地在应用程序中嵌入Redis。 持久化是数据库管理中的一个核心概念...

    redis开发运维实践指南

    Redis作为运行在内存中的数据结构服务器,其重要性在开发和运维领域日益凸显。本实践指南针对Redis的开发和运维提供了详细的操作指南,内容覆盖了从基础的数据操作到复杂的系统架构设计,适用于Redis开发和运维人员...

    springboot+redis+shiro单点登录,统一异常处理,统一日志

    总结起来,这个项目将SpringBoot的便捷性与Shiro的安全控制和Redis的高速缓存相结合,实现了高效的SSO单点登录,同时提供了统一的异常处理和日志管理机制,提高了系统的稳定性和用户体验。这是一套完整的解决方案,...

    redis数据库开发所需jar包

    总结来说,"redis数据库开发所需jar包"主要是指Jedis和Apache Commons Pool2这两个Java库,它们为Java开发者提供了一个高效、便捷的接口来与Redis数据库进行交互,是开发基于Redis的应用必不可少的工具。正确理解和...

    redis中demo文档

    Jedis是Redis官方推荐的Java客户端开发包,用于实现与Redis服务器交互的功能。 - **依赖引入**: 在Maven项目中通过pom.xml文件引入Jedis依赖。 - **存取操作**: - 存储值: 使用`set`方法。 - 获取值: 使用`get`...

    tomcat-redis依赖jar包

    在Java Web开发中,Tomcat是一个广泛使用的应用服务器,它主要负责运行Servlet和JSP应用程序。Redis则是一种高性能的键值存储系统,常用于数据缓存、消息队列等场景。将Tomcat与Redis结合使用,可以提升Web应用的...

    RedisTest.rar

    通过查看源代码,我们可以学习到如何在.NET环境中配置和初始化Redis连接,以及如何使用StackExchange.Redis执行常见的Redis操作,如设置和获取键值、操作列表、集合和有序集合、发布/订阅消息等。此外,注释可能会...

    Redis开发与运维1

    客户端管理和异常处理也是重要内容,帮助读者理解并解决常见的客户端问题。 持久化方面,讲解了RDB和AOF两种持久化机制的工作原理、优缺点及优化策略,以及如何应对持久化过程中可能出现的问题。复制章节详细阐述了...

    springmvc+mybatis+redis

    总结来说,"springmvc+mybatis+redis"的整合是现代Web开发中常见的技术栈组合,它利用SpringMVC提供灵活的控制层,MyBatis简化数据库操作,而Redis则通过高效的缓存机制优化了数据访问性能。这种组合能够帮助开发者...

    易语言的Redis协议实现:JimStone 谢栋 Redis协议客户端模块:STRedisClient

    总结来说,通过JimStone(谢栋)的STRedisClient模块,易语言开发者能够轻松地在自己的应用程序中集成Redis功能,从而实现高效的数据存储和访问。这个模块简化了与Redis的交互过程,降低了学习成本,使得易语言在...

    jedis.zip——java开发redis的工具类

    总结来说,`jedis.zip`中的`JedisTemplate`和`JedisProvider`是针对Java开发Redis的实用工具,它们帮助开发者轻松地操作Redis,同时适应主从分区的环境。`JedisTemplate`提供了一套模板化的Redis操作接口,`...

    spring + redis + sentinel 配置

    在IT行业中,Spring框架是Java应用开发的基石,它提供了丰富的功能来简化企业级应用的构建。而Redis是一个高性能的键值数据存储系统,常被用作缓存和消息代理,提升应用程序的性能和响应速度。Sentinel是Redis的一个...

    java操作redis代码和redis工具类相关包资料

    在实际开发中,一个良好的Redis工具类通常会封装这些基础操作,提供更友好的API,例如批量操作、连接池管理、异常处理等。工具类的设计应考虑线程安全、资源释放以及错误处理,以确保代码的健壮性。 总的来说,这个...

    .NET下Redis操作类

    为了更好地利用Redis的功能并优化其性能,开发人员通常会封装一个自定义的Redis操作类。此类可以帮助简化与Redis数据库的交互,并提供额外的功能如读写分离、负载均衡等。 #### 二、读写分离和负载均衡 在高并发的...

    Laravel开发-laravel-redis-fallback

    总结来说,"Laravel开发-laravel-redis-fallback"涉及的核心知识点包括: 1. Laravel缓存驱动器的概念和配置。 2. 自定义缓存驱动器的创建和注册。 3. 异常处理和回退逻辑的实现。 4. 文件系统作为缓存回退选项的...

    redis简单封装

    在实际开发中,直接使用Redis命令进行操作往往不够灵活且易出错,因此通常会对其进行简单的封装,以提供更友好的API接口,提高代码的可读性和可维护性。封装可以包括连接池管理、事务处理、异常处理、命令参数校验等...

    Redis应用场景--Redis作者谈Redis应用场景

    无论是用于实时系统开发还是构建高效的缓存系统,Redis都展现出了巨大的潜力。通过本文的介绍,相信读者已经对Redis的主要应用场景有了较为全面的认识,未来在选择合适的工具和技术栈时,能够做出更加明智的选择。

    cpp-Redis分布式事务

    总结来说,要在C++中利用Redis实现分布式事务,我们需要理解Redis的基本命令和特性,如原子操作、发布/订阅、分布式锁和Lua脚本等。同时,选择合适的C++ Redis客户端库,并注意处理并发控制和数据一致性问题,是成功...

    C#.net Redis分布式锁源码实现

    在IT行业中,尤其是在大型分布式系统的设计与开发中,分布式锁是一种关键的同步机制。本篇文章将深入探讨如何在C#.NET环境下利用Redis实现分布式锁,以及相关的核心知识点。 首先,让我们理解什么是分布式锁。...

    Redis界面可视化工具

    在开发和运维过程中,为了方便管理和操作Redis,我们通常会使用可视化工具。本文将详细介绍"Redis界面可视化工具",特别是针对Windows平台的工具——Redis Desktop Manager。 Redis Desktop Manager是一款流行且...

Global site tag (gtag.js) - Google Analytics