【问题标题】:Redis Update Sorted Set on Key ExpireRedis 在密钥过期时更新排序集
【发布时间】:2021-01-27 23:16:06
【问题描述】:

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

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

我可以有一个过程来扫描集合并不时更新它们,但最好有一些更清洁的东西。

我认为没有办法在到期时触发存储过程之类的东西,或者在排序后的集合值上设置到期时间。

我错过了什么,或者是手动的唯一方法?

【问题讨论】:

    标签: redis


    【解决方案1】:

    您是对的,您不能对已排序的集合值本身“设置过期时间”。

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

    键空间通知

    使用密钥空间通知,您可以捕获将发送 PUBLISH 消息的 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 齿轮

    使用 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() 函数。

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


    让我稍微偏离你最初的问题。

    您似乎正在使用 Sorted Set 为您的数据创建某种形式的索引。

    如果是这种情况,您应该查看 RediSearch,这是另一个 Redis 模块,它允许您索引 Hash 字段,然后使用索引进行一些高级查询和聚合。

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

    我邀请你看看:

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

    【讨论】:

    • 您的假设是正确的。我认为您建议使用 Gears 或 RediSearch 的解决方案是理想的,但我使用的是 ElastiCache,所以我认为这不是一个选择。不过使用到期通知是可行的。
    • 如果您需要托管服务,您可以使用 RedisLabs 中的 Redis Cloud 并使用 RediSearch 参见 redislabs.com/try-free/AWS —— 免责声明:我正在为 RedisLabs 工作 ;)
    猜你喜欢
    • 2020-09-26
    • 2020-04-19
    • 2016-04-25
    • 2023-03-04
    • 1970-01-01
    • 2013-09-08
    • 1970-01-01
    • 1970-01-01
    • 2023-02-17
    相关资源
    最近更新 更多