【发布时间】:2016-11-19 01:21:19
【问题描述】:
我有以下场景:
- 获取数字数组(来自 REDIS)有条件
- 为每个数字做一些异步操作(根据数字从数据库中获取一些东西)
- 对于来自 DB 的结果集中的每一件事,请执行另一个异步操作
定期重复1. 2. 3.,因为新的数字会不断添加到 REDIS 结构中。这些数字以毫秒为单位表示 unix 时间戳,因此开箱即用这些数字将始终按添加时间排序 p>
有条件地表示从 REDIS 中获取小于或等于当前 unix 时间戳(以毫秒为单位)的那些 unix 时间戳(Date.now())
问题是哪种 REDIS 数据类型最适合此用例,请记住此代码将扩展到 N 个实例,因此 N 个实例将共享对单个 REDIS 实例的访问。为了平均分担负载,每个实例将从 REDIS 读取例如第一个(最旧的)5 个数字。 数字是唯一的(添加相同的数字应该默默地失败)所以 REDIS SET 似乎是一个不错的选择,但从 REDIS 集中读取 M 个第一个元素似乎是不可能的。
为了防止两个不同的代码实例读取相同的数字,REDIS 读取操作应该是原子的,它应该读取数字并删除它们。如果对特定号码 (steps 2. and 3.) 的任何异步操作失败,则应将号码再次添加到 REDIS 以再次处理。应尽快将它们重新添加回头部而不是末端以再次处理。据我所知SADD 会把它推到最后。
SMEMBERS key 会阅读所有内容,这对我来说就像一把锤子。我需要包含一些应用程序逻辑来获得前五个,而不是检查小于或等于Date.now() 的内容,然后删除它们并以某种方式将所有内容包装在单个事务中。除此之外,设置的基数可能很大。SSCAN 听起来很有趣,但我不知道它在如上所述的“缩放”环境中是如何工作的。除此之外,根据 REDIS 文档:SCAN 系列命令仅对返回的元素提供有限的保证,因为我们增量迭代的集合在迭代过程中可能会发生变化。如上所述收藏会经常更换
【问题讨论】:
-
您是否考虑过使用带有 Lua 脚本的排序集来实现基于分数的原子弹出?如果没有,很乐意添加详细信息作为完整的答案
-
@ItamarHaber 请这样做。请检查有关条件的修改
标签: redis node-redis