使用Redis和Spring的首要任务之一是通过IoC容器连接到存储。为此,需要一个Java连接器(或绑定)。无论你选择哪个库,你只需要使用一组Spring Data Redis api(它在所有连接器上的行为一致)。org.springframework.data.redis.connection包及其RedisConnection和RedisConnectionFactory接口,用于与Redis一同工作,并检索Redis的active连接。
RedisConnection为Redis通信提供了核心模块。它还自动将底层连接库异常转换为与Spring一致的DAO异常层次结构,这样你就可以在不更改任何代码的情况下切换连接器,因为操作语义保持不变。
对于需要native library API的情况,RedisConnection提供了一个专用方法(getNativeConnection),该方法返回用于通信的原始底层对象。
Active RedisConnection对象是通过RedisConnectionFactory创建的。此外,工厂充当PersistenceExceptionTranslator对象,这意味着一旦声明,它们就可以进行透明的异常转换。例如,您可以通过使用@Repository注解和AOP来进行异常转换。有关更多信息,请参阅Spring Framework文档中的专门描述。
RedisConnection类不是线程安全的。虽然底层的本机连接,如Lettuce的StatefulRedisConnection,可能是线程安全的,但Spring Data Redis的LettuceConnection类本身不是。因此,不应在多个线程之间共享RedisConnection的实例。对于事务性或阻塞Redis操作和命令(如BLPOP)尤其如此。例如,在事务和pipelining操作中,RedisConnection保持不受保护的可变状态以正确完成操作,从而使它在多线程环境使用变得不安全。这是经过设计的。
如果出于性能或其他原因,需要在多个线程之间共享(有状态)Redis资源,如连接,则应获取native连接并直接使用Redis客户端库(驱动程序)API。或者,你可以使用RedisTemplate,它以线程安全的方式获取和管理operations (和Redis命令)的连接。有关更多详细信息,请参阅RedisTemplate文档。
根据底层配置,工厂可以返回新连接或现有连接(当使用池或共享native连接时)。
使用RedisConnectionFactory最简单的方法是通过IoC容器配置适当的连接器,并将其注入调用类。
但是,目前并不是所有的连接器都支持Redis的所有功能。在基础库不支持的Connection API上调用方法时,将引发UnsupportedOperationException。以下概述解释了各个Redis连接器支持的功能:
表1: 各Redis连接器的功能可用性
支持特性 | Lettuce | Jedis |
---|---|---|
Standalone 连接 | ✓ | ✓ |
Master/Replica 连接 | ✓ | |
Redis Sentinel | Master Lookup, Sentinel Authentication, Replica Reads | Master Lookup |
Redis Cluster | Cluster Connections, Cluster Node Connections, Replica Reads | Cluster Connections, Cluster Node Connections |
传输通道 | TCP, OS-native TCP (epoll, kqueue), Unix Domain Sockets | TCP |
连接池 | ✓(使用commons-pool2) | ✓(使用commons-pool2) |
其他连接特性 | Singleton-connection sharing for non-blocking commands | Pipelining 和Transactions 互斥。不能在pipeline/transactions使用 server/connection 命令 . |
SSL 支持 | ✓ | ✓ |
Pub/Sub | ✓ | ✓ |
Pipelining | ✓ | ✓(Pipelining 和 Transactions互斥) |
事务 | ✓ | ✓(Pipelining 和 Transactions互斥) |
Datatype 支持 | Key, String, List, Set, Sorted Set, Hash, Server, Stream, Scripting, Geo, HyperLogLog | Key, String, List, Set, Sorted Set, Hash, Server, Stream, Scripting, Geo, HyperLogLog |
Reactive (non-blocking) API | ✓ |
Lettuce是一个基于Netty的开源连接器,由Spring Data Redis通过org.springframework.data.redis.connection.lettuce包支持。将以下依赖内容添加到pom.xml文件中:
<dependencies>
<dependency>
<groupId>io.lettucegroupId>
<artifactId>lettuce-coreartifactId>
<version>6.3.1.RELEASEversion>
dependency>
dependencies>
下面的例子展示了如何创建一个新的Lettuce连接工厂:
@Configuration
class AppConfig {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(new RedisStandaloneConfiguration("server", 6379));
}
}
还有一些Lettuce特定的连接参数可以调整。默认情况下,由LettuceConnectionFactory创建的所有LettuceConnection实例共享相同的线程安全native连接,用于所有非阻塞和非事务操作。若要每次使用专用连接,请将shareNativeConnection设置为false。如果shareNativeConnection设置为false,则还可以将LettuceConnectionFactory配置为使用LettucePool来池化阻塞和事务连接或所有连接。
以下示例展示了使用LettuceClientConfigurationBuilder的更复杂的配置,包括SSL和超时:
@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 domain sockets与Redis通信。确保包含与运行时环境匹配的适当native传输依赖项。下面的例子展示了如何在/var/run/redis.sock为Unix domain socket创建一个Lettuce Connection工厂:
@Configuration
class AppConfig {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(new RedisSocketConfiguration("/var/run/redis.sock"));
}
}
Netty目前支持用于OS-native传输的epoll (Linux)和kqueue (BSD/macOS)接口。
Jedis是一个community-driven的连接器,由Spring Data Redis模块通过org.springframework.data.redis.connection.jedis包支持。
将以下依赖内容添加到pom.xml文件中:
<dependencies>
<dependency>
<groupId>redis.clientsgroupId>
<artifactId>jedisartifactId>
<version>5.0.2version>
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);
}
}