Spring CRUDRepository 的数据 Redis 问题

Spring Data Redis issue with CRUDRepository

我和我的团队正在使用带有 Redis 的 CRUD 存储库对其执行一些操作。问题是 Redis 中有一个条目作为索引生成,该索引存储与 Redis 条目关联的键,并且该条目永远不会删除 TTL 达到 0 时已经刷新的条目。

这是我们使用的代码示例。

@RedisHash("rate")
public class RateRedisEntry implements Serializable {
    @Id
    private String tenantEndpointByBlock; // A HTTP end point
    ...
}

// CRUD repository.
@Repository
public interface RateRepository extends CrudRepository<RateRedisEntry, String> {}

这会在 Redis 中生成条目 rate,即我之前提到的 Set 对象。

当我们检查它的内存使用情况时,它一直在增长,直到内存使用量达到 Redis 可用内存的 100%。'

> MEMORY USAGE "rate"
(integer) 153034
.
.
> MEMORY USAGE "rate"
(integer) 153876
.
.
> MEMORY USAGE "rate"
(integer) 163492

有没有办法阻止创建此索引或在条目的 TTL 达到 0 后删除存储的值?

感谢任何帮助。

Object-Mapping/Repositories 需要一种方法来批量查找对象 (findByKeys(id1, id2,...)) 并进行分页以及其他需要维护主键集的方法。存储库尊重 TTL 值并从创建的集合中清除 keys/ids:

The repository implementation ensures subscription to Redis keyspace notifications via RedisMessageListenerContainer.

所以我的猜测是应用程序没有收到实体 TTL 过期的键空间通知。

或者...

我认为您生成 RateRedisEntry 的速度可能无法通过键空间通知清理集合。如果是这样的话,那么我就不会使用 @RedisHash 和 Repositories,而是使用 HashMapper 和 HashOperations。参见 https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/#redis.hashmappers.root

我找到了解决问题的可能方法。您可以设置存储库选项来跟踪条目的 TTL 达到 0 的事件。

@EnableRedisRepositories(enableKeyspaceEvents 
    = EnableKeyspaceEvents.ON_STARTUP)

这将使 Spring Data Redis 跟踪刷新的条目,因此它会更新作为索引的条目。

但是,这会在您的系统上引入一些额外的处理,因此您应该意识到这一点并评估使用 RedisRepository 是否有意义。

在我们的案例中,我们决定直接使用 RedisTemplate class,以避免任何额外的开销或不受控制的处理。

如果您有兴趣了解我们如何修复它的所有细节,您可以阅读我写的这篇文章。

https://engineering.salesforce.com/lessons-learned-using-spring-data-redis-f3121f89bff9