我有一个作业队列,有多个工人在监视这个队列。(每个作业对应一个用户)。在任何给定时间,队列中每个用户可能有多个作业。
我不希望我的工人在任何给定时间内每个用户处理超过1个作业。只有在当时没有其他工作人员处理该用户的情况下,工作人员才应该挑选用户的作业。如果用户的作业正在由worker处理,我还希望下一个用户作业在完成后立即被选中。
我想保持我的工人用户不可知(即,任何工人应该能够处理任何用户的工作)。这可以帮助我横向缩放。
我该怎么做呢?我想为每个用户创建单独的队列,但这样工人将不得不观察大量的队列,可能会浪费资源。我现在使用beanstald作为队列服务器。
任何帮助都是感激的。
首先,让我说,每个用户只处理一个作业的限制可能会导致处理其他用户作业的极度延迟。考虑这样一个场景:队列包含user1的大量连续作业,然后是user2的大量连续作业,以此类推。根据您提出的体系结构,您必须首先耗尽user1作业队列,然后user2作业才会开始处理,让user3等待很长时间…
您可以通过引入多个队列(仍然不是每个用户一个队列)并以循环方式排队来缓解这种情况,但是正如您所看到的,这仍然不是100%可靠的。
但是,如果您真的想用一个(或几个)队列来保证这一要求,我实际上建议使用某种共享锁定机制(例如memcached)来在处理该用户的作业时维护每个用户的锁。本文描述了如何做到这一点,并且有一些宝石可以做到这一点。然后可以使用以下算法:
job = @beanstalkd.reserve
user_id = job.body["user_id"]
if (get_lock_for(user_id)
# process job
# ....
job.delete
end