对于最新的稳定版本,请使用 Spring Data Redis 3.3.1! |
对于最新的稳定版本,请使用 Spring Data Redis 3.3.1! |
Spring Data Redis 在包中提供了 Spring Framework 缓存抽象的实现。
要使用 Redis 作为后备实现,请添加到您的配置中,如下所示:org.springframework.data.redis.cache
RedisCacheManager
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
return RedisCacheManager.create(connectionFactory);
}
RedisCacheManager
行为可以配置为 ,允许您设置默认、事务行为和预定义的缓存。RedisCacheManagerBuilder
RedisCacheConfiguration
RedisCacheManager cacheManager = RedisCacheManager.builder(connectionFactory)
.cacheDefaults(RedisCacheConfiguration.defaultCacheConfig())
.transactionAware()
.withInitialCacheConfigurations(Collections.singletonMap("predefined",
RedisCacheConfiguration.defaultCacheConfig().disableCachingNullValues()))
.build();
如前面的示例所示,允许基于每个缓存进行自定义配置。RedisCacheManager
创建者的行为是用 定义的。
该配置允许您设置密钥过期时间、前缀和实现,以便与二进制存储格式之间转换,如以下示例所示:RedisCache
RedisCacheManager
RedisCacheConfiguration
RedisSerializer
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(1))
.disableCachingNullValues();
RedisCacheManager
默认为无锁,用于读取和写入二进制值。
无锁缓存可提高吞吐量。
缺少入口锁定可能会导致 and 操作出现重叠的非原子命令,因为这些命令需要向 Redis 发送多个命令。
锁定对应项通过设置显式锁定密钥并检查此密钥是否存在来防止命令重叠,这会导致额外的请求和潜在的命令等待时间。RedisCacheWriter
Cache
putIfAbsent
clean
锁定应用于缓存级别,而不是每个缓存条目。
可以按如下方式选择加入锁定行为:
RedisCacheManager cacheMangager = RedisCacheManager
.build(RedisCacheWriter.lockingRedisCacheWriter(connectionFactory))
.cacheDefaults(RedisCacheConfiguration.defaultCacheConfig())
...
默认情况下,任何缓存条目都以实际缓存名称为前缀,后跟两个冒号 ()。
此行为可以更改为静态前缀和计算前缀。key
::
以下示例演示如何设置静态前缀:
// static key prefix
RedisCacheConfiguration.defaultCacheConfig().prefixCacheNameWith("(͡° ᴥ ͡°)");
The following example shows how to set a computed prefix:
// computed key prefix
RedisCacheConfiguration.defaultCacheConfig()
.computePrefixWith(cacheName -> "¯\_(ツ)_/¯" + cacheName);
缓存实现默认为 use 和 clear 缓存。 可能会导致大型密钥空间出现性能问题。
因此,可以使用 切换到基于 的批处理策略创建默认值。
该策略需要批处理大小,以避免过多的 Redis 命令往返:KEYS
DEL
KEYS
RedisCacheWriter
BatchStrategy
SCAN
SCAN
RedisCacheManager cacheManager = RedisCacheManager
.build(RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory, BatchStrategies.scan(1000)))
.cacheDefaults(RedisCacheConfiguration.defaultCacheConfig())
...
使用任何驱动程序和 Redis 操作模式(独立、集群)完全支持批处理策略。 使用 Lettuce 驱动程序时完全受支持。
Jedis 仅支持非集群模式。 |
下表列出了 的默认设置:RedisCacheManager
设置 | 价值 |
---|---|
缓存编写器 |
非锁定、批量策略 |
缓存配置 |
|
初始缓存 |
没有 |
事务感知 |
不 |
下表列出了 的默认设置:RedisCacheConfiguration
密钥过期 | 没有 |
---|---|
缓存 |
是的 |
前缀键 |
是的 |
默认前缀 |
实际缓存名称 |
密钥序列化程序 |
|
值序列化程序 |
|
转换服务 |
|
默认情况下,统计信息处于禁用状态。
用于收集本地命中和未命中,返回所收集数据的快照。 |
使用任何驱动程序和 Redis 操作模式(独立、集群)完全支持批处理策略。 使用 Lettuce 驱动程序时完全受支持。
Jedis 仅支持非集群模式。 |
设置 | 价值 |
---|---|
缓存编写器 |
非锁定、批量策略 |
缓存配置 |
|
初始缓存 |
没有 |
事务感知 |
不 |
密钥过期 | 没有 |
---|---|
缓存 |
是的 |
前缀键 |
是的 |
默认前缀 |
实际缓存名称 |
密钥序列化程序 |
|
值序列化程序 |
|
转换服务 |
|
默认情况下,统计信息处于禁用状态。
用于收集本地命中和未命中,返回所收集数据的快照。 |
Redis 缓存过期
空闲时间 (TTI) 和生存时间 (TTL) 的实现在定义和行为上也各不相同,即使在不同的数据存储中也是如此。
通常:
-
生存时间 (TTL) 过期 - TTL 仅通过创建或更新数据访问操作进行设置和重置。 只要条目是在 TTL 过期超时之前写入的,包括在创建时,条目的超时将重置为 TTL 过期超时的配置持续时间。 例如,如果 TTL 过期超时设置为 5 分钟,则在创建条目时将超时设置为 5 分钟,并在此后和 5 分钟间隔到期之前更新条目时重置为 5 分钟。 如果在 5 分钟内没有发生更新,即使该条目被读取了几次,甚至在 5 分钟的间隔内只读取了一次,该条目仍将过期。 必须写入该条目,以防止在声明 TTL 过期策略时该条目过期。
-
空闲时间 (TTI) 过期 - TTI 在读取条目以及条目更新时重置,并且是 TTL 过期策略的有效和扩展。
某些数据存储在配置 TTL 时使条目过期,无论该条目上发生何种类型的数据访问操作(读取、写入或其他)。 在设置配置的 TTL 过期超时后,无论如何都会从数据存储中逐出该条目。 逐出操作(例如:销毁、失效、溢出到磁盘(对于持久性存储)等)是特定于数据存储的。 |
生存时间 (TTL) 过期
Spring Data Redis 的实现支持缓存条目的生存时间 (TTL) 过期。
用户可以通过提供新接口的实现,使用固定或动态计算的每个缓存条目来配置 TTL 过期超时。Cache
Duration
Duration
RedisCacheWriter.TtlFunction
该接口是在 Spring Data Redis 中引入的。 |
如果所有缓存条目都应在设定的持续时间后过期,则只需使用固定的 来配置 TTL 过期超时,如下所示:Duration
RedisCacheConfiguration fiveMinuteTtlExpirationDefaults =
RedisCacheConfiguration.defaultCacheConfig().enableTtl(Duration.ofMinutes(5));
但是,如果 TTL 过期超时应因缓存条目而异,则必须提供接口的自定义实现:RedisCacheWriter.TtlFunction
enum MyCustomTtlFunction implements TtlFunction {
INSTANCE;
@Override
public Duration getTimeToLive(Object key, @Nullable Object value) {
// compute a TTL expiration timeout (Duration) based on the cache entry key and/or value
}
}
在引擎盖下,固定的 TTL 过期被包装在返回提供的 . |
然后,您可以使用以下命令全局配置固定或动态的每缓存条目 TTL 过期:Duration
Duration
RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(fiveMinuteTtlExpirationDefaults)
.build();
或者,或者:
RedisCacheConfiguration defaults = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(MyCustomTtlFunction.INSTANCE);
RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(defaults)
.build();
当然,您可以使用以下方法组合全局配置和每缓存配置:
RedisCacheConfiguration predefined = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(MyCustomTtlFunction.INSTANCE);
Map<String, RedisCacheConfiguration> initialCaches = Collections.singletonMap("predefined", predefined);
RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(fiveMinuteTtlExpirationDefaults)
.withInitialCacheConfigurations(initialCaches)
.build();
空闲时间 (TTI) 到期
Redis 本身不支持真正的空闲时间 (TTI) 过期概念。 尽管如此,使用 Spring Data Redis 的 Cache 实现,仍有可能实现类似空闲时间 (TTI) 的过期行为。
Spring Data Redis 的 Cache 实现中 TTI 的配置必须显式启用,即选择加入。
此外,您还必须使用接口的固定或自定义实现提供 TTL 配置,如上文 Redis 缓存过期中所述。Duration
TtlFunction
例如:
@Configuration
@EnableCaching
class RedisConfiguration {
@Bean
RedisConnectionFactory redisConnectionFactory() {
// ...
}
@Bean
RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration defaults = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(5))
.enableTimeToIdle();
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(defaults)
.build();
}
}
由于 Redis 服务器没有实现正确的 TTI 概念,因此 TTI 只能通过接受过期选项的 Redis 命令来实现。
在 Redis 中,“过期”在技术上是一种生存时间 (TTL) 策略。
但是,在读取密钥值时可以传递 TTL 过期,从而有效地重置 TTL 过期超时,就像现在在 Spring Data Redis 的操作中一样。Cache.get(key)
RedisCache.get(key)
通过调用 Redis 命令实现。GETEX
Redis |
为了在 Spring Data Redis 应用程序中实现真正的空闲时间 (TTI) 过期行为,必须在每次读取或写入操作时一致地访问具有 (TTL) 过期的条目。
此规则没有例外。
如果要在Spring Data Redis应用程序中混合和匹配不同的数据访问模式(例如:缓存,使用和可能调用操作,或者尤其是在使用Spring Data Repository CRUD操作时),则如果设置了TTL过期,则访问条目不一定会阻止该条目过期。
例如,在具有TTL过期(即)的服务方法调用期间,条目可能会“放入”(写入)缓存中,然后在过期超时之前使用Spring Data Redis存储库读取(使用不过期选项)。
不指定过期选项的简单不会重置条目的 TTL 过期超时。
因此,该条目可能会在下一次数据访问操作之前过期,即使它刚刚被读取。
由于无法在 Redis 服务器中强制执行此操作,因此在配置空闲过期时间时,应用程序有责任在适当的情况下在缓存内外一致地访问条目。 |
某些数据存储在配置 TTL 时使条目过期,无论该条目上发生何种类型的数据访问操作(读取、写入或其他)。 在设置配置的 TTL 过期超时后,无论如何都会从数据存储中逐出该条目。 逐出操作(例如:销毁、失效、溢出到磁盘(对于持久性存储)等)是特定于数据存储的。 |
该接口是在 Spring Data Redis 中引入的。 |
在引擎盖下,固定的 TTL 过期被包装在返回提供的 . |
Redis |
为了在 Spring Data Redis 应用程序中实现真正的空闲时间 (TTI) 过期行为,必须在每次读取或写入操作时一致地访问具有 (TTL) 过期的条目。
此规则没有例外。
如果要在Spring Data Redis应用程序中混合和匹配不同的数据访问模式(例如:缓存,使用和可能调用操作,或者尤其是在使用Spring Data Repository CRUD操作时),则如果设置了TTL过期,则访问条目不一定会阻止该条目过期。
例如,在具有TTL过期(即)的服务方法调用期间,条目可能会“放入”(写入)缓存中,然后在过期超时之前使用Spring Data Redis存储库读取(使用不过期选项)。
不指定过期选项的简单不会重置条目的 TTL 过期超时。
因此,该条目可能会在下一次数据访问操作之前过期,即使它刚刚被读取。
由于无法在 Redis 服务器中强制执行此操作,因此在配置空闲过期时间时,应用程序有责任在适当的情况下在缓存内外一致地访问条目。 |