假设我们有一个要执行的任务列表,以及一些从该列表中弹出项目的工作程序。如果worker在完成任务执行之前意外崩溃,那么该任务就会丢失。什么样的机制可以防止这种情况,这样我们就可以重新处理被放弃的任务?
发布于 2021-04-21 23:36:00
您需要使用ZSET来解决此问题
弹出操作
确认操作
从ZSET中删除
Worker
您需要运行一个计划的工作进程,该工作进程将在项目过期时将其从ZSET移动到列表
请详细阅读我在Rqueue https://medium.com/@sonus21/introducing-rqueue-redis-queue-d344f5c36e1b中是如何做到的
Github代码:https://github.com/sonus21/rqueue
发布于 2021-04-22 02:24:01
set或zset成员没有EXPIRE,也没有从zset中弹出并推送到列表的原子操作。所以我结束了写这个原子运行的lua脚本。
首先,我向executing-tasks zset添加一个带有时间戳分数的任务(javascript中的(new Date()).valueOf()):
ZADD 1619028226766 executing-tasks
然后我运行脚本:
EVAL [THE SCRIPT] 2 executing-tasks tasks 1619028196766
如果任务超过30秒,它将被发送到tasks列表。如果不是,它将被发送回executing-tasks zset。
这是脚本
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" }https://stackoverflow.com/questions/67196575
复制相似问题