我正在使用Spring Data Repository保存新条目。每个条目我都有10秒的TTL。
当我保存带索引的条目时,这是我在Redis中得到的
127.0.0.1:6379> keys *
1) "job:campaignId:aa"
2) "job:a6d6e491-5d75-4fd0-bd8e-71692f6d18be"
3) "job:recipient:dd"
4) "job:a6d6e491-5d75-4fd0-bd8e-71692f6d18be:phantom"
5) "job:listId:cc"
6) "job:accountId:bb"
7) "job"
8) "job:a6d6e491-5d75-4fd0-bd8e-71692f6d18be:idx"
到期后,我仍然有数据:
127.0.0.1:6379> keys *
1) "job:campaignId:aa"
2) "job:recipient:dd"
3) "job:listId:cc"
4) "job:accountId:bb"
5) "job"
6) "job:a6d6e491-5d75-4fd0-bd8e-71692f6d18be:idx"
没有任何TTL。
他们为什么不删除自己?我怎么能这样做?
答案 0 :(得分:13)
Spring Data Redis存储库使用多个Redis功能在Redis中保留域对象。
域对象主要存储在哈希(job:a6d6e491-5d75-4fd0-bd8e-71692f6d18be
)中。任何到期都直接应用于哈希,因此Redis可以使密钥到期。 Spring Data Redis还维护二级索引(job:campaignId:aa
,job:recipient:dd
)以提供特定字段值的查找。集合中的各个元素不能过期。只有整个数据结构可以过期,但这不是你想要做的事情,因为所有未过期的元素都会以这种方式消失。
因此,Spring Data Redis将原始哈希的副本保留为幻像哈希(job:a6d6e491-5d75-4fd0-bd8e-71692f6d18be:phantom
),并且TTL略长。
Spring Data Redis订阅密钥事件(设置为@EnableRedisRepositories(enableKeyspaceEvents = EnableKeyspaceEvents.ON_STARTUP
)以监听到期事件。一旦原始哈希值到期,Spring Data Redis就会加载幻像哈希来执行清理(从二级索引中删除引用)。
未执行数据清理的原因有多种原因:
@EnableRedisRepositories
启用了存储库支持(未启用keyspace-events),则Keyspace事件侦听器不活动,并且Spring Data Redis未订阅任何到期事件。 答案 1 :(得分:0)
如果您没有设置过期时间,则不会自动删除任何键/值。
因此,要自动删除数据,您必须设置过期时间。
redis> SET mykey "Hello"
"OK"
redis> EXPIRE mykey 10
(integer) 1
参考:https://redis.io/commands/expire
以下是将数据添加到redis并设置到期时间的Spring代码段
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String, String> template;
@Resource(name = "redisTemplate")
ValueOperations<String, String> ops;
public boolean addValue(String key, String value) {
if (template.hasKey(Constants.REDIS_KEY_PREFIX + key)) {
// key is already there
return false;
} else {
ops.set(Constants.REDIS_KEY_PREFIX + key, value);
template.expireAt(Constants.REDIS_KEY_PREFIX + key, 10);
}
return true;
}
}