跳到主要内容

驱动程序

DeepSeek V3 中英对照 Drivers

在使用 Redis 和 Spring 时,首要任务之一是通过 IoC 容器连接到存储。为此,需要一个 Java 连接器(或绑定)。无论选择哪个库,你只需要使用一套 Spring Data Redis API(它在所有连接器中表现一致)。org.springframework.data.redis.connection 包及其 RedisConnectionRedisConnectionFactory 接口用于处理和获取与 Redis 的活动连接。

RedisConnection 和 RedisConnectionFactory {#redis:connectors:connection}

RedisConnection 提供了 Redis 通信的核心构建块,因为它负责与 Redis 后端进行通信。它还会自动将底层连接库的异常转换为 Spring 一致的 DAO 异常层次结构,这样你可以在不更改任何代码的情况下切换连接器,因为操作语义保持不变。

备注

对于需要使用原生库 API 的极端情况,RedisConnection 提供了一个专用方法(getNativeConnection),它返回用于通信的原始底层对象。

活动的 RedisConnection 对象是通过 RedisConnectionFactory 创建的。此外,该工厂还充当 PersistenceExceptionTranslator 对象,这意味着一旦声明,它们可以让你进行透明的异常转换。例如,你可以通过使用 @Repository 注解和 AOP 来实现异常转换。更多信息,请参阅 Spring Framework 文档中的相关章节

备注

RedisConnection不是线程安全的。尽管底层的本地连接(例如 Lettuce 的 StatefulRedisConnection)可能是线程安全的,但 Spring Data Redis 的 LettuceConnection 类本身并不是线程安全的。因此,您不应该在多个线程之间共享 RedisConnection 的实例。特别是在处理事务性或阻塞性的 Redis 操作和命令(例如 BLPOP)时,这一点尤为重要。例如,在事务和流水线操作中,RedisConnection 会持有未受保护的可变状态以正确完成操作,这使得它在多线程中使用时变得不安全。这是设计上的考虑。

提示

如果你需要跨多个线程共享(有状态的)Redis 资源,例如连接,无论是出于性能原因还是其他原因,你应该获取原生连接并直接使用 Redis 客户端库(驱动)API。或者,你可以使用 RedisTemplate,它以线程安全的方式获取并管理操作(和 Redis 命令)的连接。有关 RedisTemplate 的更多详细信息,请参阅文档

备注

根据底层配置的不同,工厂可以返回一个新连接或一个现有连接(当使用连接池或共享原生连接时)。

使用 RedisConnectionFactory 最简单的方法是通过 IoC 容器配置适当的连接器,并将其注入到使用它的类中。

遗憾的是,目前并非所有连接器都支持所有的 Redis 功能。当调用 Connection API 中底层库不支持的方法时,会抛出 UnsupportedOperationException 异常。以下概述解释了各个 Redis 连接器所支持的功能:

表 1. Redis 连接器的功能可用性

支持的功能LettuceJedis
独立连接XX
主/从连接X
Redis Sentinel主节点查找,Sentinel 认证,从节点读取主节点查找
Redis 集群集群连接,集群节点连接,从节点读取集群连接,集群节点连接
传输通道TCP,操作系统原生 TCP(epoll、kqueue),Unix 域套接字TCP
连接池X(使用 commons-pool2X(使用 commons-pool2
其他连接功能非阻塞命令的单例连接共享管道和事务互斥。不能在管道/事务中使用服务器/连接命令。
SSL 支持XX
发布/订阅XX
管道XX(管道和事务互斥)
事务XX(管道和事务互斥)
数据类型支持键、字符串、列表、集合、有序集合、哈希、服务器、流、脚本、地理、HyperLogLog键、字符串、列表、集合、有序集合、哈希、服务器、流、脚本、地理、HyperLogLog
响应式(非阻塞)APIX

配置 Lettuce 连接器 {#redis:connectors:lettuce}

Lettuce 是一个基于 Netty 的开源连接器,通过 org.springframework.data.redis.connection.lettuce 包得到 Spring Data Redis 的支持。

<dependencies>

<!-- other dependency elements omitted -->

<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>6.4.1.RELEASE</version>
</dependency>

</dependencies>
xml

以下示例展示了如何创建一个新的 Lettuce 连接工厂:

@Configuration
class AppConfig {

@Bean
public LettuceConnectionFactory redisConnectionFactory() {

return new LettuceConnectionFactory(new RedisStandaloneConfiguration("server", 6379));
}
}
java

还有一些 Lettuce 特定的连接参数可以进行微调。默认情况下,LettuceConnectionFactory 创建的所有 LettuceConnection 实例在所有非阻塞和非事务操作中共享同一个线程安全的原生连接。如果希望每次使用专用连接,可以将 shareNativeConnection 设置为 falseLettuceConnectionFactory 还可以配置为使用 LettucePool 来池化阻塞和事务连接,或者如果 shareNativeConnection 设置为 false,则可以池化所有连接。

以下示例展示了一个更为复杂的配置,包括 SSL 和超时设置,使用了 LettuceClientConfigurationBuilder

@Bean
public LettuceConnectionFactory lettuceConnectionFactory() {

LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
.useSsl().and()
.commandTimeout(Duration.ofSeconds(2))
.shutdownTimeout(Duration.ZERO)
.build();

return new LettuceConnectionFactory(new RedisStandaloneConfiguration("localhost", 6379), clientConfig);
}
java

如需更详细的客户端配置调整,请参阅 LettuceClientConfiguration

Lettuce 集成了 Netty 的原生传输,允许你使用 Unix 域套接字与 Redis 进行通信。请确保包含与你的运行时环境匹配的适当原生传输依赖项。以下示例展示了如何为位于 /var/run/redis.sock 的 Unix 域套接字创建 Lettuce 连接工厂:

@Configuration
class AppConfig {

@Bean
public LettuceConnectionFactory redisConnectionFactory() {

return new LettuceConnectionFactory(new RedisSocketConfiguration("/var/run/redis.sock"));
}
}
java
备注

Netty 目前支持 epoll(Linux)和 kqueue(BSD/macOS)接口用于操作系统原生传输。

配置 Jedis 连接器 {#redis:connectors:jedis}

Jedis 是一个由社区驱动的连接器,通过 org.springframework.data.redis.connection.jedis 包得到 Spring Data Redis 模块的支持。

<dependencies>

<!-- other dependency elements omitted -->

<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>5.2.0</version>
</dependency>

</dependencies>
xml

最简单的 Jedis 配置如下所示:

@Configuration
class AppConfig {

@Bean
public JedisConnectionFactory redisConnectionFactory() {
return new JedisConnectionFactory();
}
}
java

然而,对于生产环境,您可能需要调整一些设置,例如主机或密码,如下例所示:

@Configuration
class RedisConfiguration {

@Bean
public JedisConnectionFactory redisConnectionFactory() {

RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("server", 6379);
return new JedisConnectionFactory(config);
}
}
java