Hash 如何";“到期”;";HSET“;redis中的子密钥?
为了安全起见,我需要使redis哈希中的所有密钥过期,这些密钥的过期时间超过1个月。 Redis的创造者安提雷斯说: 嗨,这是不可能的,或者使用不同的顶级键 特定字段,或与该字段一起存储另一个带有 过期时间,获取两者,并让应用程序了解它是否过期 仍然有效或不基于当前时间Hash 如何";“到期”;";HSET“;redis中的子密钥?,hash,redis,Hash,Redis,为了安全起见,我需要使redis哈希中的所有密钥过期,这些密钥的过期时间超过1个月。 Redis的创造者安提雷斯说: 嗨,这是不可能的,或者使用不同的顶级键 特定字段,或与该字段一起存储另一个带有 过期时间,获取两者,并让应用程序了解它是否过期 仍然有效或不基于当前时间 你可以。这里有一个例子 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> 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
使用或命令
如果要使哈希表中的特定密钥过期超过1个月。这是不可能的。
Redis expire命令用于哈希中的所有键。
如果设置每日哈希键,则可以设置生存时间的键
hset key-20140325 f1 1
expire key-20140325 100
hset key-20140325 f1 2
有一个java框架,它实现了hashMap
对象,并支持条目TTL。它在引擎盖下使用hmap
和zset
Redis对象。用法示例:
RMapCache map=redisson.getMapCache('map');
地图。放置(1,30,时间单位。天);//此条目将在30天后过期
这种方法非常有用。关于NodeJS实现,我在散列中保存的对象中添加了一个自定义的
expiryTime
字段。然后在特定的时间段后,我使用以下代码清除过期的哈希项:
client.hgetall(散列名称、函数(err、reply){
若有(答复){
Object.key(reply.forEach)(key=>{
if(reply[key]&&JSON.parse(reply[key]).expiryTime<(新日期).getTime()){
hdel(散列名称、密钥);
}
})
}
});
您可以轻松地使Redis哈希过期,
例如使用python
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> hgetall testt
(empty list or set)
与redis cli相同
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"
10秒后
127.0.0.1:6379> hgetall testt
(empty list or set)
为了实现这一点,您可以在Redis中以不同的方式存储键/值,只需在存储键时为它们添加前缀或命名空间,例如“hset\ux”
- 获取一个键/值
等于Get hset_key
HGET hset key
- 添加一个键/值
等于SET hset_key value
hset hset key
- 获取所有钥匙
等于keys hset.*
HGETALL hset
- 获取所有VAL应在2次操作中完成,首先获取所有键
然后获取每个键的值keys hset.*
- 添加带有TTL或expire的键/值,这是问题的主题:
键
将在整个数据库中查找匹配的键,这可能会影响性能,尤其是当您的数据库很大时
注:
将在整个数据库中查找匹配的密钥,这可能会影响性能,尤其是在您有大型数据库的情况下。虽然密钥
可能更好,只要它不阻塞服务器,但在大型数据库的情况下,性能仍然是一个问题SCAN 0 MATCH hset.*
- 您可以创建一个新的数据库,分别存储这些要过期的密钥,特别是当它们是一小组密钥时
键
您可以通过使用
psubscribe
和使用Redis键空间通知__keyevent@__:过期“
这样,每次密钥过期时,您都会在redis连接上发布一条消息
关于您的问题,基本上您可以使用set
创建一个临时“正常”密钥,过期时间为s/ms。它应该与您希望在集合中删除的密钥的名称相匹配
因为您的临时密钥将被发布到您的redis连接中,并持有“__keyevent@0__:expired“
当密钥过期时,您可以轻松地从原始密钥集中删除密钥,因为消息中将显示密钥的名称
在该页面上有一个简单的实践示例:
doc:(查找标志xE)您可以在redis中使用排序集来获得一个带有时间戳作为分数的TTL容器。 例如,每当在集合中插入事件字符串时,都可以将其分数设置为事件时间。 因此,您可以通过调用
zrangebyscore“您的设置名称”最小时间最大时间
此外,我们可以通过使用zremrangebyscore“yourset name”min time max time
删除旧事件来实现过期
这里唯一的缺点是您必须从一个外部进程进行内务处理,以保持集合的大小 Redis不支持将
TTL
放在除top键以外的散列上,这将使整个散列过期。如果您使用的是分片集群,那么可以使用另一种方法。这种方法不可能在所有场景中都有用,而且性能特征可能与预期的不同。仍然值得一提的是:
当有散列时,结构基本上如下所示:
hash_top_key
- child_key_1 -> some_value
- child_key_2 -> some_value
...
- child_key_n -> some_value
由于我们希望将TTL
添加到子键,因此可以将它们移动到顶部键。主要的一点是,现在的键应该是散列\u top\u键
和子键的组合:
{hash_top_key}child_key_1 -> some_value
{hash_top_key}child_key_2 -> some_value
...
{hash_top_key}child_key_n -> some_value
我们故意使用{}
符号。这允许所有这些键落在相同的哈希槽中。您可以在此处阅读更多信息:
现在,如果我们想对哈希进行相同的操作,我们可以:
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
。首先,我们为所有子密钥获取哈希槽。然后我们获取特定哈希槽的键,最后我们检索值。在这里我们需要小心,因为对于散列槽
,可能有多个n
键,而且可能有我们不感兴趣的键,但它们具有相同的散列槽
。我们实际上可以编写一个Lua
脚本来在服务器中执行这些步骤
hash_name
- field_1: "2021-01-15;123"
- field_2: "2021-01-20;125"
- field_2: "2021-02-01;127"
val = redis.hget(hash_name, field_1)
timestamp = val.substring(0, val.index_of(";"))
if now() > timestamp:
new_val = get_updated_value()
new_timestamp = now() + EXPIRY_LENGTH
redis.hset(hash_name, field_1, new_timestamp + ";" + new_val)
val = new_val
else:
val = val.substring(val.index_of(";"))
// proceed to use val