您好,登錄后才能下訂單哦!
這篇文章主要講解了“Redis command timed out兩種異常情況怎么解決”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Redis command timed out兩種異常情況怎么解決”吧!
SpringBoot項目引入Redis后發現偶爾會出現連接會超時Redis command timed out,看了博客上寫的很多文章,都說可以通過設置超時時間解決問題,嘗試的一下還是會出現這個問題,其實不管你設置多久都還是會超時。
原因是springboot2.x之后,springboot默認使用的Redis的客戶端是lettuce,而不是jedis,lettuce連接池。
org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 5 second(s) at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:70) at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:41) at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44) at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:42) at org.springframework.data.redis.connection.lettuce.LettuceConnection.convertLettuceAccessException(LettuceConnection.java:273) at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.convertLettuceAccessException(LettuceStringCommands.java:799) at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.get(LettuceStringCommands.java:68) at org.springframework.data.redis.connection.DefaultedRedisConnection.get(DefaultedRedisConnection.java:266) at org.springframework.data.redis.core.DefaultValueOperations$1.inRedis(DefaultValueOperations.java:57) at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:60)
引入spring-boot-starter-data-redis包,這個包會默認使用 lettuce ,這個問題就lettuce引起的,我們只需要把io.lettuce包移除,換成jedis就可以了
<!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <exclusions> <!-- 過濾lettuce,使用jedis作為redis客戶端 --> <exclusion> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>
二、keys命令會遍歷redis集合,是一個非常耗時的操作,線上應該禁止使用此操作,通過業務排查發現有一個業務還使用了keys 命令來過濾數據,線上代碼中使用了keys 命令來過濾key keys命令類似與數據庫的全表掃描,會遍歷redis中的所有數據,而redis的work線程又是單線程的,這個命令執行時間過長會阻塞其他正常命令的執行,導致其他命令執行超時,出現前面問題中的timed out 異常。
解決:
了解到keys 命令的影響,禁止使用keys 命令,特別是線上環境,禁止使用redis desktop manager 這樣的redis 界面工具連接線上環境(因為這類工具會通過keys * 來加載全量數據到本地),排查代碼中使用keys 命令的情況,必須在redis 服務器上禁止keys 這樣不安全的命令的使用,還有flushdb flushall等操作。
三、spring-boot-starter-data-redis有兩種實現方式:lettuce 和 jedis 區別
1.Jedis:
Jedis是同步的,不支持異步,Jedis客戶端實例不是線程安全的,需要每個線程一個Jedis實例,所以一般通過連接池來使用Jedis。
優點:
提供了比較全面的 Redis 操作特性的 API
API 基本與 Redis 的指令一一對應,使用簡單易理解
缺點:
同步阻塞 IO
不支持異步
線程不安全
springboot鏈接Redis客戶端Jedis的pom.xml配置
<!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <exclusions> <!-- 過濾lettuce,使用jedis作為redis客戶端 --> <exclusion> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </exclusion> </exclusions> </dependency> <!-- jedis--> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>
jedis的yml文件配置如下:
#Redis哨兵模式 spring: redis: database: 1 password: 123456 jedis: pool: max-active: 8 min-idle: 0 max-idle: 8 sentinel: master: mymaster nodes: 192.168.111.10:26379,192.168.111.11:26379,192.168.111.12:26379
2.Lettuce:
Lettuce是基于Netty框架的事件驅動的Redis客戶端,其方法調用是異步的,Lettuce的API也是線程安全的,所以多個線程可以操作單個Lettuce連接來完成各種操作,同時Lettuce也支持連接池.
優點:
線程安全
基于 Netty 框架的事件驅動的通信,可異步調用
適用于分布式緩存
缺點:
API 更抽象,學習使用成本高
springboot鏈接Redis客戶端Jedis的pom.xml配置
<!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- spring2.X集成redis需要common-pool2依賴,如果使用Lettuce作為連接池, 需要引入commons-pool2依賴,否則會報錯bean注入失敗 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency>
jedis的yml文件配置如下:
#Redis哨兵模式 spring: redis: database: 1 lettuce: pool: max-active: 20 max-idle: 10 max-wait: 10000 min-idle: 0 shutdown-timeout: 100 password: 123456 sentinel: master: mymaster nodes: 192.168.111.10:26379,192.168.111.11:26379,192.168.111.12:26379 timeout: 3000
感謝各位的閱讀,以上就是“Redis command timed out兩種異常情況怎么解決”的內容了,經過本文的學習后,相信大家對Redis command timed out兩種異常情況怎么解決這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。