【问题标题】:Redis reliable queues for multi threaded processing用于多线程处理的 Redis 可靠队列
【发布时间】:2015-06-25 03:16:57
【问题描述】:

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

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

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

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

BRPOPLPUSH <primary-queue> <thread-specific-processing-queue>

然后为了清理超时对象,我的监控线程必须监控所有这些线程特定的处理队列。

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

【问题讨论】:

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

标签: redis reliable-message-delivery


【解决方案1】:

@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 列表)。

【讨论】:

    猜你喜欢
    • 2015-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-12
    • 2017-12-28
    • 2018-12-05
    • 1970-01-01
    • 2013-01-23
    相关资源
    最近更新 更多