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
我和我的团队正在使用带有 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