我正在创建一个由客户端(webbrowsers)通过AJAX检索的事件系统。对于事件存储,我只想使用Redis。
我了解了Redis中的一些不错的功能,例如 EXPIRE - 一个允许自动执行某种垃圾收集工作的命令,因此不需要自己实现等效的(提供)该解决方案将与Redis一样高效)。确实,非常好,我将使用它。
但是,我偶然发现了一个问题,即如何存储与Redis的字符串数据类型的unix时间戳编号相关的问题。此号码应用于:
所以简而言之,我希望有一些像Strings一样的 SCORE 功能,但不一定与Redis中的排序集一起使用。而且我不喜欢这里提出的解决方案实际使用集合:Redis: possible to expire an element in an array or sorted set?
相反,我只需要创建一个非常常见的事件队列来发送给客户端。这个队列应该:
所以我现在的解决方案是:
但是如何创建:
"WHERE "*" > given_unixtime_number"
参与Redis?
修改 当然,我不打算坚持上述解决方案。例如,如果需要,我可以使用非命名空间的字符串创建一个单独的Redis实例(例如,仅将{unix-time-stamp}作为键,而不使用EVENT和eventName部分)。
答案 0 :(得分:1)
您确实想使用排序集,以及如何:
使用"命名空间" Redis字符串的键:EVENT:{unix-time-stamp}:eventName,值为事件的内容
我不确定eventName
的用途是什么,但这看起来不错。您还可以跳过EVENT
前缀并为每个密钥保存5个字节。如果您有大量事件,请考虑使用hash" buckets"如http://redis.io/topics/memory-optimization#using-hashes-to-abstract-a-very-memory-efficient-plain-key-value-store-on-top-of-redis所述。
按键模式获取所有字符串(事件):EVENT:*
这实际上是一个关键点 - 你如何有效地做到这一点?答案:不要使用KEYS
或SCAN
,而是保留"索引"所有这些钥匙。常规(即未分类)设置对于这些是足够好的,但由于您需要基于纪元的排序,排序集是正确的选择。
我们称之为排序集 events
。每当您创建新活动时,例如SET EVENT:123:foo bar
,使用纪元作为得分events
将该事件的关键名称添加到ZADD events 123 EVENT:123:foo
。
通过一些Redis命令获取最新的Strings(事件)(我不知道):EVENT:* WHERE" *" > given_unixtime_number
命令为ZRANGEBYSCORE
(或ZREVRANGEBYSCORE
,具体取决于您希望如何排序结果),如下所示:ZRANGEBYSCORE events (given_unixtime_number +inf
。这将返回所有相关的关键名称,然后您需要GET
它们(可能的优化是将它包装在Lua脚本中以来回保存)。请注意使用左括号((
)表示独占搜索(即>
而不是>=
)
管理:"费用"这种方法的一个方面是你必须维护events
"索引"。通过在events
上使用ZREMBYSCORE
命令,您可以轻松删除过期的元素 - 定期(例如每1秒)或根据您的需要执行的每个操作。实际事件'密钥可以是EXPIRE
d(尽管您可能会在events
已排序的设置中持续过期的密钥一段时间)或DEL
已经过了&#34 ;人工"通过向处理events
的到期逻辑添加循环。