【Azure Redis 緩存 Azure Cache For Redis】Redis出現 java.net.SocketTimeoutException: Read timed out 異常


問題描述

在使用Azure Redis時,遇見Read Timed out異常, Redis的客戶端使用的時jedis。問題發生時,執行redis部分指令出錯,大部分get指令,set指令能正常執行。 但程序間段性還是出現Read Timed out錯誤。

Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
    at redis.clients.util.Pool.getResource(Pool.java:53)
    at redis.clients.jedis.JedisPool.getResource(JedisPool.java:226)
    at redis.clients.jedis.JedisPool.getResource(JedisPool.java:16)
    at io.terminus.session.redis.JedisPoolExecutor.execute(JedisPoolExecutor.java:56)
    at io.terminus.session.redis.SessionRedisSource.findSessionById(SessionRedisSource.java:61)
    ... 58 common frames omitted
Caused by: 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.getStatusCodeReply(Connection.java:239)
    at redis.clients.jedis.BinaryJedis.auth(BinaryJedis.java:2139)
    at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:108)
    at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:868)
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:435)
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363)
    at redis.clients.util.Pool.getResource(Pool.java:49)
    ... 62 common frames omitted
Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:170)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at java.net.SocketInputStream.read(SocketInputStream.java:127)
    at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:196)
    ... 73 common frames omitted

異常分析

從異常分析,當前客戶端與Redis服務器的連接已經建立成功,但是在執行某些指令時,出現超時情況,而根據Jedis默認對JedisPool中設置的超時時間2秒作為判斷標准,需要在Redis服務器中查看是否時執行某些命令時間超過了2秒。可以通過showlog指令顯示出日志記錄。

If you get java.net.SocketTimeoutException: Read timed out exception

Try setting own timeout value when constructing JedisPool using the following constructor:

JedisPool(GenericObjectPoolConfig poolConfig, String host, int port, int timeout)

where timeout is given as milliseconds.

Default timeout value is 2 seconds.

在Redis的日志中,查看到執行KEYS命令時,超過了2秒

 

解決辦法

在知道異常的根源是由於執行KEYS,超過了2秒的超時時間。解決辦法有兩點,

  • 替換KEYS命令,因為KEYS命令回全Redis鍵值掃描,非常消耗資源。而在Redis的官方推薦中也建議使用SCAN來替代它。

  • 增加timeout時間,把默認的超時時間2秒,增加到5秒

 

參考文檔

If you get java.net.SocketTimeoutException: Read timed out exception:https://github.com/xetorthio/jedis/wiki/FAQ#if-you-get-javanetsockettimeoutexception-read-timed-out-exception

KEYS: https://redis.io/commands/keys

SCANhttps://redis.io/commands/scan

 


免責聲明!

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



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