密钥过期时Redis更新排序集

时间:2020-10-13 15:25:20

标签: redis

我有一个Redis服务器,其中包含一组键值对和一个排序后的集合,提供这些键值对的键的索引。

键值对可以进入“已完成”状态,此时,它们将需要在1小时后删除。 可以通过在密钥上设置有效期限来简单地实现此目的,但是从排序集中清除密钥似乎更麻烦。

我可以有一个过程,可以不时扫描这些集并进行更新,但是最好有一些清洁的东西。

我不认为有一种方法可以在到期时触发诸如存储过程之类的东西,或者对排序后的设置值设置到期时间。

我想念的一切还是唯一的方法?

1 个答案:

答案 0 :(得分:3)

您是正确的,您不能对已排序的设置值本身进行“过期”。

但是您可以使用主键并在到期时捕获事件。您至少有两种方法可以实现此目的:

密钥空间通知

使用“密钥空间通知”,您可以捕获EXPIRE事件,该事件将发送发布消息,然后您可以使用该消息。

让我解释一下基本流程:

配置通知

CONFIG SET notify-keyspace-events Ex
  • E :键上发生的事件
  • x :捕获过期的事件

现在,您的数据库将在__key*__:*频道上发布事件。

因此,您可以构建一个侦听这些事件的服务(直接或间接)更新集合:

psubscribe __key*__:*

如果您的应用程序设置了以下值和有效期

set foo bar EX 5

您应该收到以下消息

1) "pmessage"
2) "__key*__:*"
3) "__keyevent@0__:expired"
4) "foo"

Redis Gears

使用Redis Gears,您可以捕获相同的事件(它也基于通知),但是直接在Redis数据库中编写代码会更容易。

您可以按以下方式创建Gears :(这是一个Python脚本,我正在使用RedisInsight将其部署到Redis)

def process(x):
    execute('LPUSH', 'expired:keys', x['value']['key']);

# Capture an expiration event and adds it to 'expired:events' stream
cap = GB('KeysReader')
cap.foreach(lambda x:
            execute('XADD', 'expired:events', '*', 'key', x['key']))
cap.register(prefix='*',
             mode='sync',
             eventTypes=['expired'],
             readValue=False)

# Consume new messages from expiration streams and process them somehow
proc = GB('StreamReader')
proc.foreach(process)
proc.register(prefix='expired:*',
              batch=100,
              duration=1, 
              trimStream = False)

看一下cap = GB('KeysReader')开头的部分

  • 这将侦听prefix='*'eventTypes=['expired']的任何密钥到期
  • 如果到期,它将使用XADD命令向'expired:events' Redis流添加一条消息
  • 然后查看将处理流的功能proc = GB('StreamReader')
  • 每次流中有新消息时,它将调用process()函数。

您可以添加您的逻辑以更新此功能中的排序集。在我的示例中,我刚刚将过期密钥添加到列表中。


让我与您最初的问题有所不同。

您似乎正在使用“排序集”为数据创建某种形式的索引。

在这种情况下,您应该查看RediSearch,这是另一个Redis模块,允许您为哈希字段建立索引,然后使用索引进行一些高级查询和汇总。

使用RediSearch,您不需要添加任何代码来管理索引,它是由数据库自动完成的,您可以在字段中查询。

我邀请您来看看:

很抱歉,如果这不是您使用Sorted Set的原因,但是我认为值得检查一下,因此,如果您今天手动管理索引,可以简化很多应用程序代码。