• 解决Jedis异常之 java.lang.ClassCastException: java.lang.Long cannot be cast to [B


    问题描述

    使用jedis sdk访问redis时,有时会抛如下异常

    java.lang.ClassCastException: java.lang.Long cannot be cast to [B
    	at redis.clients.jedis.Connection.getBinaryBulkReply(Connection.java:259)
    	at redis.clients.jedis.Connection.getBulkReply(Connection.java:248)
    	at redis.clients.jedis.Jedis.hget(Jedis.java:674)
    

    有时可能还会伴随着超时异常:

    redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
    	at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:202)
    	at redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40)
    	at redis.clients.jedis.Protocol.process(Protocol.java:151)
    	at redis.clients.jedis.Protocol.read(Protocol.java:215)
    	at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:340)
    	at redis.clients.jedis.Connection.getBinaryBulkReply(Connection.java:259)
    	at redis.clients.jedis.Connection.getBulkReply(Connection.java:248)
    	at redis.clients.jedis.Jedis.hget(Jedis.java:674)
    

    原因&解决

    主要有以下三类原因:

    1. 一个jedis连接在使用时抛出异常(如超时异常)后被返回连接池,这个连接下次使用时就可能跑类似异常,具体跟sockt buffer有上次请求数据的有关,参考链接1。

      针对这种情况,需要将jedis正确close,有些文章可能会说需要调用returnBrokenResource方法,这已经是个远古方法了,至少在2.9.0以上,直接close即可,如果进行了异常捕获,则需要在finally中进行close。

    2. 多线程访问jedis对象

      根据jedis的文档,JedisPool线程安全而Jedis非线程安全,检查代码是否有多线程逻辑。

    3. redis集群资源负载重、写满等

      我这里就是这个原因,代码中对redis先读后写,不停抛这个异常。如果注释掉写,只读运行没问题。注释掉读,就开始抛下面的异常,这种负载重抛异常的情况在链接2的issue也有人提及。

      redis.clients.jedis.exceptions.JedisDataException: ERR 
      	at redis.clients.jedis.Protocol.processError(Protocol.java:127)
      	at redis.clients.jedis.Protocol.process(Protocol.java:161)
      	at redis.clients.jedis.Protocol.read(Protocol.java:215)
      	at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:340)
      	at redis.clients.jedis.Connection.getOne(Connection.java:322)
      	at redis.clients.jedis.ShardedJedisPipeline.sync(ShardedJedisPipeline.java:44)
      

      最后找运维申请了个新redis就正常读写了,如果你们redis是自己的维护的,就检查下日志吧。

    参考资料:

    1. https://stackoverflow.com/questions/40769135/jedis-java-lang-long-cannot-be-cast-to-b

    2. https://github.com/redis/jedis/issues/186

    3. https://www.pianshen.com/article/70711745627/

  • 相关阅读:
    React全家桶+AntD 共享单车后台管理系统开发
    eclipse中通过Properties Editor插件查看配置文件中Unicode内容
    修改eclipse的编码格式
    后端接收前端数据中文乱码解决方案
    MySQL基础
    wordpress个人常用标签调用
    4gl游标cursor
    尝试写一写4gl与4fd
    foreach循環體控制
    保护wordpress后台登录地址
  • 原文地址:https://www.cnblogs.com/lshao/p/15215442.html
Copyright © 2020-2023  润新知