用于多线程处理的Redis可靠队列

用于多线程处理的Redis可靠队列,redis,reliable-message-delivery,Redis,Reliable Message Delivery,对于我正在进行的项目,我正在使用Redis跨多个进程分发消息。现在,我应该让他们变得可靠 我考虑通过BropPurPress命令使用可靠的队列模式。此模式建议处理线程在作业成功完成后,通过lrem命令从“处理列表”中删除消息的额外副本 当我使用多个线程弹出时,弹出项的额外副本从多个线程进入处理列表。也就是说,处理队列包含由多个线程弹出的元素。因此,如果一个线程完成了它的工作,它就不知道从“处理队列”中删除哪个项 为了克服这个问题,我认为应该基于threadId维护多个处理队列(每个线程一个)。因

对于我正在进行的项目,我正在使用Redis跨多个进程分发消息。现在,我应该让他们变得可靠

我考虑通过BropPurPress命令使用可靠的队列模式。此模式建议处理线程在作业成功完成后,通过lrem命令从“处理列表”中删除消息的额外副本

当我使用多个线程弹出时,弹出项的额外副本从多个线程进入处理列表。也就是说,处理队列包含由多个线程弹出的元素。因此,如果一个线程完成了它的工作,它就不知道从“处理队列”中删除哪个项

为了克服这个问题,我认为应该基于threadId维护多个处理队列(每个线程一个)。因此,我的BRPOPLPUSH将是:

BRPOPLPUSH <primary-queue> <thread-specific-processing-queue>
BRPOPLPUSH
然后,为了清理timedout对象,我的监视线程必须监视所有这些特定于线程的处理队列

有没有比上面设想的更好的方法来解决这个问题?

@user779159

为了支持可靠的队列机制,我们采用以下方法:

 - two data structures
    -- Redis List (the original queue from which items are popped regularly)
    -- a Redis z-set, which temporarily stores the popped item.
算法:

-- When an element is popped, we store in z-set 
-- If the task that picked the item completed its job, it will delete the entry from z-set.
-- If the task couldn't complete it, the item will be hanging around in z-set. So we know, whether a task was done within expected time or not.
-- Now, another background process periodically scans this z-set, picks up items which are timedout, and then puts them back to queue
如何做到:

  • 我们使用zset来存储我们弹出的项(通常使用lua) 脚本)
  • 我们将超时值存储为该项的排名/分数
  • 另一个扫描程序进程将定期(比如每分钟)运行 z-set命令zrangebyscore,用于选择介于(现在和最后1个)之间的项目 分钟)
  • 如果有通过上述命令找到的项目,这意味着 弹出项目的进程(通过brpop)尚未完成其操作 及时完成任务
  • 因此,第二个过程将把项目放回 队列(redis列表)最初所属的位置

IMO这是有道理的。如果我那么担心可靠性,那么为这个操作替换Redis是有意义的。我考虑了同样的问题,最终得到了同样的解决方案,但是在哪里存储每个“线程特定处理队列”的确切最后修改时间为了理解哪个应该被清除,我最终存储了一个redis z-set,而不是一个队列。因此,失效时间是z-集中元素的分数。然后我使用redis调度模式根据分数扫描z集,然后将过期的密钥放回主队列。@MupparthyRavindranath我有类似的要求,你说的“redis调度模式”是什么意思?@MupparthyRavindranath:那么我们可以说,BRPOPLPUSH实现人员从未考虑过处理此类消息的多线程方面,因为在C#客户机实现中考虑它时,我面临着同样的问题。