本文介绍了Redis 在密钥过期时更新排序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Redis server with a set of key value pairs and a sorted set providing an index of the keys of those key value pairs.

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

The key value pairs can enter a "completed" state and at this point they will need to be deleted after 1 hour.This can be simply achieved by setting an expiry on the keys, but clearing them from the sorted set appears to be more problematic.

我可以有一个过程来扫描集合并不时更新它们,但如果有一些更清晰的东西会很好.

I could have a process that scans the sets and updates them from time to time, but it would be nice to have something a bit cleaner.

我认为没有办法在到期时触发诸如存储过程之类的东西或在排序的集合值上设置到期.

I don't think there is a way to trigger something like a stored procedure on expiry or set an expiry on the sorted set values.

有什么我遗漏的吗,或者手动是唯一的方法?

Anything I've missed, or is manual the only way?

推荐答案

你说得对,你不能设置到期";排序的集合值本身.

You are correct you cannot "put an expiry" on the sorted set value itself.

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

But you can work with the main key and capture the event when the expiration occurs. You have at least 2 ways to achieve this:

按键空间通知

使用密钥空间通知,您可以捕获 EXPIRE 事件,该事件将发送您可以使用的 PUBLISH 消息.

Using Key Space Notification, you can capture the EXPIRE event that will send a PUBLISH message that you can then consume.

让我解释一下基本流程:

Let me explain the basic flow:

配置通知

CONFIG SET notify-keyspace-events Ex

  • E:键上发生的事件
  • x:捕获过期事件
    • E : events happening on keys
    • x : capture expired events
    • 现在您的数据库将在 __key*__:* 频道上发布一个事件.

      Now your database will publish an event on the __key*__:* channel.

      所以你可以构建一个服务来监听这些事件更新集合(直接或间接):

      So you can build a service that listen to these event update the set (directly or indirectly):

      psubscribe __key*__:*
      

      如果您的应用程序设置了以下值和到期时间

      If you have an application that set the following value and expiration

      set foo bar EX 5
      

      您应该会收到以下消息

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

      Redis 齿轮

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

      Using Redis Gears, you capture the same event (it is based on notification too), but it is easier to write code directly in your Redis Database.

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

      You can create a Gears as follow: (this is a Python script, I am using RedisInsight to deploy it to 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 Stream 添加一条消息
      • 然后查看将处理流的函数 proc = GB('StreamReader')
      • 每次有新消息出现在流中时,它都会调用 process() 函数.
      • This will listen to any key expiration prefix='*' & eventTypes=['expired']
      • In case of expiration it will add a message to the 'expired:events' Redis Stream using the XADD command
      • Then look at the function proc = GB('StreamReader') that will process the streams
      • each time a new message is in the stream it will call the process() function.

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

      You can add your logic to update the sorted set in this function. In my example I have just added the expired key to a list.

      让我与你最初的问题有点不同.

      Let me diverge a little bit from your initial question.

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

      It looks like you are using Sorted Set to create some form of indexing for your data.

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

      If this is the case, you should look at RediSearch, another Redis module that allow you to index Hash fields and then use the index to do some advanced queries and aggregation.

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

      With RediSearch you do not need to add any code to manage the index, it is done automatically by the database, and you can query on the fields.

      我邀请你看:

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

      Sorry if this is not the reason you are using Sorted Set, but I think it is worth checking as thus could simplify a lot your application code if you do manage index manually today.

      这篇关于Redis 在密钥过期时更新排序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-07 03:26