Redis command timed out
SpringBoot项目引入Redis后发现偶尔会出现连接会超时Redis command timed out,看了博客上写的很多文章,都说可以通过设置超时时间解决问题,尝试的一下还是会出现这个问题,其实不管你设置多久都还是会超时。原因是springboot2.x之后,springboot默认使用的Redis的客户端是lettuce,而不是jedis,lettuce连接池。
解决办法,我们通过引入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>
spring-boot-starter-data-redis
是 Spring Boot 的一个 starter,它简化了在 Spring Boot 项目中集成和使用 Redis 的过程。在 spring-boot-starter-data-redis
中,有两种常见的 Redis 客户端实现:Lettuce 和 Jedis。以下是它们之间的主要区别:
连接池:
Lettuce:Lettuce 提供了自己的连接池,这意味着它能够更好地控制和管理 Redis 连接。它提供了更高级的特性,如连接的复用、连接的自动恢复等。
Jedis:Jedis 使用的是 Jedis 提供的连接池。虽然 Jedis 连接池在一定程度上也很有用,但与 Lettuce 相比,它可能不是最优的解决方案。
异步操作:
Lettuce:Lettuce 支持完全的异步操作,这意味着所有的 Redis 命令都是异步执行的,不会阻塞主线程。这使得在高并发场景下,性能表现更好。
Jedis:Jedis 主要支持同步操作。虽然 Jedis 也提供了一些异步 API,但与 Lettuce 相比,它的异步支持可能不够全面和强大。
高级特性:
Lettuce:Lettuce 支持 Redis 的事务功能、发布/订阅模式以及 Lua 脚本执行等高级特性。
Jedis:Jedis 也支持这些特性,但在某些方面可能没有 Lettuce 那么强大或灵活。
社区和支持:
Lettuce:Lettuce 的社区相对较小,但它是 Spring Data Redis 的默认客户端。由于它是 Spring 的一部分,因此得到了官方的支持和维护。
Jedis:Jedis 的社区更大、更活跃。由于它的历史更长,因此有更多的教程、文档和示例可供参考。
资源消耗:
在某些情况下,使用 Lettuce 可能比使用 Jedis 更节省内存和 CPU 资源,因为它更加高效。
默认情况下springboot使用lecttuce,如果要使用jedis,可以在pom文件排除。
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
接下来看下示例,以下是使用 Lettuce 的简单示例:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
@Component
public class RedisExample {
private final StringRedisTemplate stringRedisTemplate;
@Autowired
public RedisExample(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
public void setValue(String key, String value) {
stringRedisTemplate.opsForValue().set(key, value);
}
public String getValue(String key) {
return stringRedisTemplate.opsForValue().get(key);
}
}
以下是使用 Jedis 的简单示例:
import redis.clients.jedis.Jedis;
import org.springframework.stereotype.Component;
@Component
public class JedisExample {
private final Jedis jedis;
public JedisExample(Jedis jedis) {
this.jedis = jedis;
}
public void setValue(String key, String value) {
jedis.set(key, value);
}
public String getValue(String key) {
return jedis.get(key);
}
}
最后要提醒大家的是,根据您的项目需求和偏好,您可以选择最适合您的客户端。如果您的项目需要高性能和高级特性,并且您更喜欢完全异步的操作,那么 Lettuce 可能是一个更好的选择。如果您更喜欢一个活跃的社区、大量的教程和文档,并且对连接池的要求不是特别高,那么 Jedis 可能更适合您。