我们有以下用例:每次某个密钥过期时,我们都需要得到通知,并根据其值执行某些操作.但是当redis触发expired事件时,当我们稍后try 访问它时,密钥已经从数据库中删除,这当然是意料之中的.

现在有没有办法在条目过期后再次访问它?我想不是.

那么第二种 Select :有没有一种方法可以告诉redis在发送这些事件时发布整个值对象,而不仅仅是键?我想它可以通过Lua添加,但如果可能的话,我会对更简单的选项感兴趣.对于其他事件,我们也需要此行为,我们基本上需要所有通知来发布值,而不是键(我们可以在收到事件后执行GET,但我们希望绕过第二个调用,主要是为了有一个原子过程,因为在发布事件和执行GET来检索值之间,值可能已经改变).

希望这是可以理解的.也许我们看不到显而易见的东西,所以提前谢谢你!

推荐答案

ELI链接的功能允许您监听密钥何时过期.但是,它不会给您提供密钥的值.此外,基于filed github issue,看起来您不能期望在短期内构建此功能(如果有的话).我使用的解决方案是创建一个特殊的"影子"到期密钥,该密钥链接到您具有实际值的密钥.

假设您有一个名为testkey的密钥,它的整数值为100.此外,密钥将在10秒后过期,此时您想要获取密钥的值.(可能您在密钥存在的10秒内递增了密钥).

首先,需要设置按键空间事件的监听.特别是你想要听expired个事件.您可以通过配置或使用redis中的config set命令来执行此操作.(更多信息请参见此处:http://redis.io/topics/notifications)

CONFIG SET notify-keyspace-events Ex

现在您可以订阅一个特殊的keyevent频道,在那里您将收到密钥过期的通知.

SUBSCRIBE __keyevent@0__:expired

要订阅的频道格式为__keyevent@<db>__:<eventName>.在我们的示例中,我们假设使用的是默认数据库0,并且希望侦听expired事件.

testkey过期时,您现在将在__keyevent__通道中收到一条消息,该消息是过期密钥的名称.当然,此时密钥已不存在,因此我们无法再访问该值!解决方案是使用一个特殊的过期密钥.

当您创建testkey时,还要创建一个特殊的过期"影子"密钥(不要过期实际的testkey).例如:

SET testkey 100
SET shadowkey:testkey "" EX 10

现在,在__keyevent@0__:expired通道中,您将收到一条消息,告诉您密钥shadowkey:testkey已过期.获取消息的值(这是键的名称),拆分冒号(或您决定使用的任何分隔符),然后手动获取键的值并将其删除.

// set your key value
SET testkey 100 
//set your "shadow" key, note the value here is irrelevant
SET shadowkey:testkey "" EX 10 
// Get an expiration message in the channel __keyevent@0__:expired
// Split the key on ":", take the second part to get your original key
// Then get the value and do whatever with it
GET testkey
// Then delete the key
DEL testkey

请注意,没有使用shadowkey的值,因此您希望使用最小的值,根据这个答案(Redis store key without a value),它是一个空字符串"".这是一个多一点的工作,以设置,但上述系统正是你所需要的.开销是实际检索和删除密钥所需的几个额外命令,加上一个空密钥的存储成本.

Database相关问答推荐

位置运算符($)工作不正确

在MongoDB的树形 struct 中更新具有给定id的元素

在使用FT.AGGREGATE聚合数据时,如何在Redis上解析ISO 8601时间?

华为Appcube中的对象字段类型

Spring Data JPA 对 SQL 注入安全吗

用于存储食谱的数据库设计

mysql搜索表名的段

在 MongoDB 中模拟关系

Android - SQLite 数据库存储在哪里?

设置默认数据库连接 Rails

mysql,dump,数据库restore恢复

如何在一行中显示 redis 中的所有键?

JPA:处理 OptimisticLockException 的模式

为什么在连接表上有一个主键不好?

具有多列的单个固定表与灵活的抽象表

Python中准备好的语句和参数化查询之间的混淆

数据库触发器的命名约定

数据库与平面文本文件:当性能不是问题时, Select 一个而不是另一个的一些技术原因是什么?

为 django 模型自动创建数据的工具

将查询限制为一条记录会提高性能吗