我找到了 Resque:
而且我可以看到我可以安排延迟的作业。我的问题是,它如何检查延迟的工作?如果我在一个月内有 5000 个延迟作业,我希望它不会每 10 秒检查一次所有延迟作业。
那么它是如何完成的呢?
我找到了 Resque:
而且我可以看到我可以安排延迟的作业。我的问题是,它如何检查延迟的工作?如果我在一个月内有 5000 个延迟作业,我希望它不会每 10 秒检查一次所有延迟作业。
那么它是如何完成的呢?
它不必检查所有延迟的作业。它在 Redis 中维护一个排序集,作业按预定时间排序。请参阅以下代码:
https://github.com/elucid/resque-delayed/blob/master/lib/resque-delayed/resque-delayed.rb
每次守护进程唤醒时,只需要检查集合中的第一项(使用 ZRANGEBYSCORE 命令)。守护进程一一获取相关作业,直到轮询查询没有返回结果,然后它再次休眠。
通过获取 n 乘 n 的作业可以进一步提高性能。它可以使用服务器端 Lua 脚本作为轮询查询来实现:
local res = redis.call('ZRANGEBYSCORE',KEYS[1], "-inf", ARGV[1], 'LIMIT', 0, 10 )
if #res > 0 then
redis.call( 'ZREMRANGEBYRANK', KEYS[1], 0, #res-1 )
return res
else
return false
end
在一次往返中,此脚本获得 10 个作业(如果可用),并将它们从 zset 中删除。比 Resque-delayed 目前需要的 11 ZRANGEBYSCORE 和 10 ZREM 好得多。