我需要使用redis散列中的所有密钥到期,这些密钥早于1个月。
This is not possible,为了keeping Redis simple。
Quis Antirez,Redis的创造者:
嗨,这是不可能的,要么为该特定字段使用不同的顶级密钥,要么与提交的另一个字段一起存储过期时间,同时获取两者,并让应用程序了解它是否仍然有效当前时间。
有一个Redisson java框架,它实现了具有入口TTL支持的哈希Map
对象。它使用引擎盖下的hmap
和zset
Redis对象。用法示例:
RMapCache<Integer, String> map = redisson.getMapCache('map');
map.put(1, 30, TimeUnit.DAYS); // this entry expires in 30 days
这种方法非常有用。
关于NodeJS实现,我在HASH中保存的对象中添加了自定义expiryTime
字段。然后在一段特定的时间后,我使用以下代码清除过期的HASH条目:
client.hgetall(HASH_NAME, function(err, reply) {
if (reply) {
Object.keys(reply).forEach(key => {
if (reply[key] && JSON.parse(reply[key]).expiryTime < (new Date).getTime()) {
client.hdel(HASH_NAME, key);
}
})
}
});
您可以通过不同方式存储Redis中的键/值来实现此目的,只需在存储键时为键添加前缀或命名空间即可。 “hset_”
GET hset_key
等于HGET hset key
SET hset_key value
等于HSET hset key
KEYS hset_*
等于HGETALL hset
KEYS hset_*
注意: SET hset_key value
EXPIRE hset_key
将查找匹配整个数据库中的密钥,这可能会影响性能,尤其是如果您有大数据库。
注意:
KEYS
将查找匹配整个数据库中的密钥,这可能会影响性能,尤其是如果您有大数据库。 KEYS
可能会更好,只要它不阻止服务器,但在大数据库的情况下性能仍然是一个问题。感谢@DanFarrell,他强调了与
SCAN 0 MATCH hset_*
相关的性能问题
Redis不支持在除顶键之外的哈希上使用KEYS
,这会使整个哈希值到期。如果您使用的是分片群集,则可以使用另一种方法。这种方法在所有情况下都没有用,性能特征可能与预期的不同。还是值得一提的是:
有哈希时,结构基本上如下:
TTL
由于我们想将hash_top_key
- child_key_1 -> some_value
- child_key_2 -> some_value
...
- child_key_n -> some_value
添加到子键,我们可以将它们移动到顶键。重点是,密钥现在应该是TTL
和子密钥的组合:
hash_top_key
我们故意使用{hash_top_key}child_key_1 -> some_value
{hash_top_key}child_key_2 -> some_value
...
{hash_top_key}child_key_n -> some_value
表示法。这允许所有这些键落在相同的{}
中。你可以在这里阅读更多相关信息:hash slot
现在,如果我们想要对哈希进行相同的操作,我们可以这样做:
https://redis.io/topics/cluster-tutorial
这里有趣的是HDEL hash_top_key child_key_1 => DEL {hash_top_key}child_key_1
HGET hash_top_key child_key_1 => GET {hash_top_key}child_key_1
HSET hash_top_key child_key_1 some_value => SET {hash_top_key}child_key_1 some_value [some_TTL]
HGETALL hash_top_key =>
keyslot = CLUSTER KEYSLOT {hash_top_key}
keys = CLUSTER GETKEYSINSLOT keyslot n
MGET keys
。首先,我们为所有儿童钥匙获得HGETALL
。然后我们得到特定hash slot
的键,最后我们检索值。我们需要在这里小心,因为hash slot
可能有更多n
键,也可能有我们不感兴趣的键,但他们有相同的hash slot
。我们实际上可以编写一个hash slot
脚本,通过执行Lua
或EVAL
命令在服务器中执行这些步骤。同样,您需要考虑针对您的特定方案的此方法的性能。
更多参考资料:
您可以。这是一个例子。
https://redis.io/commands/eval
使用redis 127.0.0.1:6379> hset key f1 1
(integer) 1
redis 127.0.0.1:6379> hset key f2 2
(integer) 1
redis 127.0.0.1:6379> hvals key
1) "1"
2) "1"
3) "2"
redis 127.0.0.1:6379> expire key 10
(integer) 1
redis 127.0.0.1:6379> hvals key
1) "1"
2) "1"
3) "2"
redis 127.0.0.1:6379> hvals key
1) "1"
2) "1"
3) "2"
redis 127.0.0.1:6379> hvals key
或EXPIRE命令。
如果您希望在超过1个月的哈希值中使特定键失效。这是不可能的。 Redis expire命令用于散列中的所有键。如果设置每日哈希键,则可以设置密钥生存时间。
EXPIREAT
你可以轻松过期Redis哈希,例如使用python
hset key-20140325 f1 1
expire key-20140325 100
hset key-20140325 f1 2
这将在10秒后使散列hashed_user中的所有子键失效
同样来自redis-cli,
import redis
conn = redis.Redis('localhost')
conn.hmset("hashed_user", {'name': 'robert', 'age': 32})
conn.expire("hashed_user", 10)
10秒后
127.0.0.1:6379> HMSET testt username wlc password P1pp0 age 34
OK
127.0.0.1:6379> hgetall testt
1) "username"
2) "wlc"
3) "password"
4) "P1pp0"
5) "age"
6) "34"
127.0.0.1:6379> expire testt 10
(integer) 1
127.0.0.1:6379> hgetall testt
1) "username"
2) "wlc"
3) "password"
4) "P1pp0"
5) "age"
6) "34"
您可以使用127.0.0.1:6379> hgetall testt
(empty list or set)
和psubscribe
来使用Redis Keyspace Notifications。
这样,每次密钥到期时,您都会在redis连接上发布消息。
关于你的问题基本上你使用"__keyevent@<DB-INDEX>__:expired"
创建一个临时的“正常”密钥,其过期时间为s / ms。它应该与您要在集合中删除的密钥的名称相匹配。
由于临时密钥将在过期时发布到持有set
的redis连接,因此您可以轻松地从原始密钥中删除密钥,因为邮件将具有密钥的名称。
该页面上的一个简单例子:"__keyevent@0__:expired"
您可以在redis中使用Sorted Set来获取时间戳为分数的TTL容器。例如,每当您将事件字符串插入集合时,您都可以将其分数设置为事件时间。因此,您可以通过调用https://redis.io/topics/notifications获取任何时间窗口的数据
此外,我们可以通过使用zrangebyscore "your set name" min-time max-time
删除旧事件来到期。
这里唯一的缺点是你必须从局外人进程做家务,以保持集合的大小。