List redis:原子LPOP和SADD可能吗?

List redis:原子LPOP和SADD可能吗?,list,queue,redis,set,List,Queue,Redis,Set,是否存在从列表中自动弹出项目并将其添加到集合中的方法 我的案例场景是,我有一个唯一项的“工作队列”列表,我想跟踪“正在进行”集合中正在处理的内容。如果我的工作进程在处理某个项目时崩溃,这也将允许“进行中”集中的项目重新排队 我希望它是原子的,这样从列表中弹出的任何内容都将始终在集合中。我就是不知道如何使用MULTI/EXEC实现这一点,即: redis> MULTI OK redis> LPOP workqueue "foobar" redis> SADD inprog "fo

是否存在从列表中自动弹出项目并将其添加到集合中的方法

我的案例场景是,我有一个唯一项的“工作队列”列表,我想跟踪“正在进行”集合中正在处理的内容。如果我的工作进程在处理某个项目时崩溃,这也将允许“进行中”集中的项目重新排队

我希望它是原子的,这样从列表中弹出的任何内容都将始终在集合中。我就是不知道如何使用MULTI/EXEC实现这一点,即:

redis> MULTI
OK
redis> LPOP workqueue
"foobar"
redis> SADD inprog "foobar"
redis> EXEC

似乎MULTI/EXEC不起作用,因为第二个命令取决于第一个命令的返回值,但在调用EXEC之前,两个命令都不会执行。如果您使用的是Redis2.6(目前在RC中),您可能可以通过使用lua脚本

总的来说,我不认为原子性在这里是个大问题。在这种情况下,没有真正的比赛条件。唯一可能发生的坏事情是,如果服务器在从队列中弹出项目并将其添加到集合中的时间段内崩溃,这似乎不太可能

为什么您希望您的“正在进行”收藏是一套?您可以简单地为正在进行的项目使用一个列表

“Right Pop,Left Push”命令正是针对这个用例生成的

以原子方式返回并删除列表的最后一个元素(尾部) 存储在源位置,并将元素推送到第一个元素(头部) 存储在目的地的列表的


如果确实要为正在进行的项目使用集合,则必须使用lua脚本并使用调用。

同意答案的multi/exec和eval部分。但我不同意原子性不是一个问题。如果有多个客户端试图并行推送/弹出,则会出现竞争条件。这个bug将非常难以追踪,因为集合似乎是更合适的数据结构。由于可能会有多个工作进程添加到“进行中”结构中,我认为从“进行中”列表中完成/删除项目会更困难,效率也会更低(即,推送/弹出项目时的动态索引)。但是我刚刚注意到用于列表的LREM命令,它可以工作,因为我的所有项目都是唯一的。但是,删除项的效率仍然较低:在本例中,SREM是O(1),LREM是O(n),其中n是列表的长度。+1这是一个很好的原因。因为您的进程列表是有界的,所以O(n)应该一点也不重要,它不会很昂贵。我可以补充一点,一小部分整数实际上会有O(logn)的时间复杂度,因为它是作为一个整数集实现的。但在实践中,这些都无关紧要,因为列表或集合是有界的。@SripathiKrishnan集合作为队列消息存储的一个使用案例是,当消息可以从重复数据消除中受益时——例如,重复缓存请求消息只能处理一次,并且跳过一些无用的处理。