【问题标题】:Redis Queues - How to resumeRedis 队列 - 如何恢复
【发布时间】:2021-04-21 13:06:02
【问题描述】:

假设我们有一个要执行的任务列表和一些从该列表中弹出项目的工作人员。 如果工作人员在完成任务执行之前意外崩溃,则该任务将丢失。 什么样的机制可以防止这种情况发生,以便我们可以重新处理废弃的任务?

【问题讨论】:

  • 你在使用 Redis Streams 吗?
  • 不,我不是。使用列表。

标签: redis queue


【解决方案1】:

你需要使用 ZSET 来解决这个问题

弹出操作

  • 添加到具有到期时间的 ZSET
  • 从列表中删除

确认操作

  • 从 ZSET 中删除

工人

您需要运行一个调度的工作程序,如果它们过期,它将把项目从 ZSET 移动到列表

详细阅读,我在Rqueue中是怎么做的https://medium.com/@sonus21/introducing-rqueue-redis-queue-d344f5c36e1b

Github 代码:https://github.com/sonus21/rqueue

【讨论】:

    【解决方案2】:

    set 或 zset 成员没有EXPIRE,并且没有从 zset 弹出并推送到列表的原子操作。所以我写完了这个原子运行的 lua 脚本。

    首先我向executing-tasks zset 添加一个带有时间戳分数的任务((new Date()).valueOf() in javascript):

    ZADD 1619028226766 executing-tasks

    然后我运行脚本:

    EVAL [THE SCRIPT] 2 executing-tasks tasks 1619028196766

    如果任务超过 30 秒,它将被发送到tasks 列表。如果没有,它将被发送回executing-taskszset。

    这是脚本

      local source = KEYS[1]
      local destination = KEYS[2]
      local min_score = ARGV[1]
      local popped = redis.call('zpopmin', source)
      local id = popped[1]
      local score = popped[2]
      if table.getn(popped) > 0 then
        if score < min_score then
          redis.call('rpush', destination, id)
          return { "RESTORED", id }
        else
          redis.call('zadd', source, score, id)
          return { "SENT_BACK", id }
        end
      end
      return { "NOTHING_DONE" }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-24
      • 1970-01-01
      • 2020-06-08
      • 1970-01-01
      • 2020-03-25
      • 1970-01-01
      • 2015-03-08
      相关资源
      最近更新 更多