|
此版本仍在开发中,尚未被视为稳定版本。如需使用最新稳定版本,请访问 Spring Data Redis 4.0.4! |
驱动程序
使用 Redis 和 Spring 时,首要任务之一是通过 IoC 容器连接到存储。
为此,需要一个 Java 连接器(或绑定)。
无论你选择哪个库,都只需使用一套 Spring Data Redis API(这些 API 在所有连接器中行为一致)。
org.springframework.data.redis.connection 包及其 RedisConnection 和 RedisConnectionFactory 接口用于操作 Redis 并获取活跃的连接。
RedisConnection 和 RedisConnectionFactory
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 命令)获取和管理连接。
有关 xref page 的更多详细信息,请参阅文档。 |
| 根据底层配置的不同,工厂可以返回一个新连接或一个现有连接(当使用连接池或共享的原生连接时)。 |
使用 RedisConnectionFactory 最简单的方式是通过 IoC 容器配置相应的连接器,并将其注入到使用该连接器的类中。
遗憾的是,目前并非所有连接器都支持全部 Redis 功能。
当调用 Connection API 中底层库不支持的方法时,会抛出 UnsupportedOperationException 异常。
以下概览说明了各个 Redis 连接器所支持的功能:
| 支持的功能 | Lettuce | Jedis |
|---|---|---|
独立连接 |
X |
X |
X |
||
主节点查找、哨兵认证、从节点读取 |
主数据查询 |
|
集群连接、集群节点连接、副本读取 |
集群连接,集群节点连接 |
|
传输通道 |
TCP、操作系统原生 TCP(epoll、kqueue)、Unix 域套接字 |
TCP |
连接池 |
X(使用 |
X(使用 |
其他连接特性 |
非阻塞命令的单例连接共享 |
管道(Pipelining)与事务(Transactions)互斥。不能在管道或事务中使用服务器/连接命令。 |
SSL 支持 |
X |
X |
X |
X |
|
X |
X(流水线与事务互斥) |
|
X |
X(流水线与事务互斥) |
|
数据类型支持 |
键、字符串、列表、集合、有序集合、哈希、服务器、流、脚本、地理空间、HyperLogLog |
键、字符串、列表、集合、有序集合、哈希、服务器、流、脚本、地理空间、HyperLogLog |
响应式(非阻塞)API |
X |
配置 Lettuce 连接器
Lettuce 是一个基于 Netty 的开源连接器,通过 org.springframework.data.redis.connection.lettuce 包被 Spring Data Redis 所支持。
dependencies 元素中:<dependencies>
<!-- other dependency elements omitted -->
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>6.8.2.RELEASE</version>
</dependency>
</dependencies>
以下示例展示了如何创建一个新的 Lettuce 连接工厂:
@Configuration
class AppConfig {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(new RedisStandaloneConfiguration("server", 6379));
}
}
还有一些特定于 Lettuce 的连接参数可以进行调整。
默认情况下,由 LettuceConnection 创建的所有 LettuceConnectionFactory 实例在所有非阻塞和非事务性操作中共享同一个线程安全的原生连接。
若要每次使用专用连接,请将 shareNativeConnection 设置为 false。LettuceConnectionFactory 也可以配置为使用 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);
}
有关更详细的客户端配置调整,请参阅 LettuceClientConfiguration。
Lettuce 集成了 Netty 的原生传输(native transports),使您能够使用 Unix 域套接字与 Redis 进行通信。
请确保包含与您的运行环境相匹配的适当原生传输依赖项。
以下示例展示了如何为位于 /var/run/redis.sock 的 Unix 域套接字创建一个 Lettuce 连接工厂:
@Configuration
class AppConfig {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(new RedisSocketConfiguration("/var/run/redis.sock"));
}
}
| Netty 目前支持用于操作系统原生传输的 epoll(Linux)和 kqueue(BSD/macOS)接口。 |
配置 Jedis 连接器
Jedis 是一个社区驱动的连接器,由 Spring Data Redis 模块通过 org.springframework.data.redis.connection.jedis 包提供支持。
dependencies 元素中:<dependencies>
<!-- other dependency elements omitted -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>7.0.0</version>
</dependency>
</dependencies>
在其最简单的形式中,Jedis 配置如下所示:
@Configuration
class AppConfig {
@Bean
public JedisConnectionFactory redisConnectionFactory() {
return new JedisConnectionFactory();
}
}
然而,在生产环境中,你可能需要调整一些设置,例如主机或密码,如下例所示:
@Configuration
class RedisConfiguration {
@Bean
public JedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("server", 6379);
return new JedisConnectionFactory(config);
}
}