设计一个作业排队系统,其中每个用户只能在任何给定时间处理一个作业

时间:2013-04-10 17:16:33

标签: architecture worker beanstalkd job-queue

我有一个单独的作业队列,有多个工作人员在看这个队列。 (每个作业对应一个用户)。在任何给定时间,队列中每个用户可能有多个作业。

我不希望我的员工在任何给定时间处理每个用户超过1个工作。只有当时没有其他工作人员处理此用户时,才应由工作人员选择用户的工作。如果工作人员正在处理用户的工作,我还希望下一个用户工作在完成后立即被选中。

我希望让我的员工与用户无关(即,任何员工都应该能够处理任何用户的工作)。这有助于我横向扩展。

我应该怎么做?我虽然为每个用​​户创建单独的队列,但工作人员必须观察大量队列并可能浪费资源。我现在正在使用beanstalkd作为队列服务器。

感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

首先,我要说限制每个用户只处理一个作业可能会导致其他用户处理作业的极端延迟。考虑一种情况,当您的队列包含user1的大量连续数量的作业,然后是user2的大量连续作业数,依此类推。由于您提出的体系结构,您将不得不耗尽user1作业的队列首先,然后只有user2作业才会开始处理,让user3等待很长时间......

您可以通过引入多个队列(仍然不是每个用户一个)并以循环方式排队工作来缓解这种情况,但正如您所看到的那样,这仍然不是100%可靠。

但是,如果你真的想用一个(或几个)队列来保证这个要求,我实际上会建议使用某种共享锁定机制(例如memcached)来维护每个用户的锁定。该用户正在处理中。 This article描述了如何以及gems来做到这一点。 然后您可以使用以下算法:

job = @beanstalkd.reserve
user_id = job.body["user_id"]
if (get_lock_for(user_id)
  # process job
  # ....
  job.delete
end