【问题标题】:Redis strings as special arraysRedis 字符串作为特殊数组
【发布时间】:2015-11-07 16:47:17
【问题描述】:

我正在创建一个由客户端(网络浏览器)通过 AJAX 检索的事件系统。对于事件存储,我只想使用 Redis。

我了解了 Redis 中的一些不错的功能,例如 EXPIRE - 一个允许自动执行某种垃圾收集工作的命令,因此无需自己实现类似的功能(前提是该解决方案将与 Redis 一样有效)。确实,很不错,我会用的。

但后来,我偶然发现了一个问题,如何存储与 Redis 的 Strings 数据类型 unix 时间戳号相关的一个问题。此号码应用于:

  • 对整个“数据集”进行排序 - 所有事件
  • 最重要的是,仅获取高于给定数字(即 > given_time)的事件记录(字符串)

简而言之,我希望有类似 SCORE 与字符串相关的功能,但不一定要与 Redis 中的 Sorted Sets 一起使用。而且我不喜欢这里提出的解决方案实际上是一种集合:​​Redis: possible to expire an element in an array or sorted set?

相反,我只需要创建一个不常见的事件队列以发送给客户端。这个队列应该:

  • 将要(通过 AJAX)获取的事件存储到“队列”中 - 为此,我想使用简单的 Redis 字符串
  • 仅提供相关时间戳高于上一个请求之一的事件
  • 在“发布”后 1 小时后过期(删除)事件(因为否则,不必要的数据量当然会增加到无穷大)

所以我目前的解决方案是:

  • 对 Redis 字符串使用“命名空间”键:EVENT:{unix-time-stamp}:eventName,并将值作为事件内容
  • 通过键模式获取所有字符串(事件):EVENT:*
  • 通过一些 Redis 命令(我不知道)获取最新的字符串(事件):EVENT:* WHERE "*" > given_unixtime_number

但是如何创建:

"WHERE "*" > given_unixtime_number"

加入 Redis?

编辑: 当然,我不打算坚持上述解决方案。例如,如果需要,我可能会使用非命名空间字符串创建一个单独的 Redis 实例(例如,仅将 {unix-time-stamp} 作为键,没有 EVENT 和 eventName 部分)。

【问题讨论】:

    标签: redis


    【解决方案1】:

    您确实想使用 Sorted Sets,方法如下:

    对 Redis 字符串使用“命名空间”键:EVENT:{unix-time-stamp}:eventName,并将值作为事件内容

    我不确定eventName 的用途是什么,但这看起来已经足够好了。您还可以跳过 EVENT 前缀并为每个键节省 5 个字节。如果您有大量事件,请考虑使用 http://redis.io/topics/memory-optimization#using-hashes-to-abstract-a-very-memory-efficient-plain-key-value-store-on-top-of-redis 中所述的哈希“桶”。

    通过按键模式获取所有字符串(事件):EVENT:*

    这实际上是一个关键点——你如何有效地做到这一点?答案:不要使用KEYSSCAN,而是保留所有这些键的“索引”。常规(即未排序的)Set 足以满足这些要求,但由于您想要基于 epoch 的排序,因此 Sorted Set 是正确的选择。

    我们称之为排序集 events。每当您创建新事件时,例如SET EVENT:123:foo bar,将该事件的键名添加到events,使用纪元作为分数:ZADD events 123 EVENT:123:foo

    通过一些 Redis 命令(我不知道)获取最新的字符串(事件): EVENT:* WHERE "*" > given_unixtime_number

    命令将是ZRANGEBYSCORE(或ZREVRANGEBYSCORE,具体取决于您希望结果的排序方式),如下所示:ZRANGEBYSCORE events (given_unixtime_number +inf。这将返回所有相关的键名,然后您需要 GET 它们(可能的优化是将其包装在 Lua 脚本中以保存来回)。请注意使用左括号 (() 表示排他搜索(即> 而不是>=

    管理:这种方法的“成本”是您必须维护events“索引”。通过在events 上使用ZREMBYSCORE 命令,您可以轻松删除过期元素 - 定期调用它(例如每 1 秒)或根据需要执行的每个操作。实际事件的密钥可以是EXPIREd(尽管您可能会在一段时间内在events Sorted Set 中得到过期的密钥)或DELeted “手动”添加处理events的过期逻辑循环。

    【讨论】:

    • 谢谢!对我来说听起来很明智,我会尽快实现它。但是,与此同时,我也了解了 Redis Pub/Sub 解决方案。你认为这个 Redis Pub/Sub 功能可以应用在我的案例中吗?
    • 不是你当前的设计——AJAX 主要是轮询,对吧? PubSub 就像广播一样,通常不会发送给 Web 客户端
    猜你喜欢
    • 1970-01-01
    • 2016-01-27
    • 2013-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-09
    相关资源
    最近更新 更多