解決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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM