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

Architecture 设计一个作业排队系统,在该系统中,每个用户在任何给定时间内只能处理一个作业,architecture,worker,beanstalkd,job-queue,Architecture,Worker,Beanstalkd,Job Queue,我有一个工作队列,有多个工人在监视这个队列。(每个作业对应一个用户)。在任何给定时间,队列中每个用户可能有多个作业 我不希望我的员工在任何给定时间处理每个用户超过1个作业。只有在没有其他工作人员处理该用户时,工作人员才应选择该用户的作业。如果某个用户的作业正在由工作人员处理,我还希望下一个用户作业完成后立即被选中 我想让我的工人用户不可知(即,任何工人都应该能够处理任何用户的工作)。这将帮助我水平缩放 我该怎么做呢?我曾考虑过为每个用户创建单独的队列,但这样一来,工作人员将不得不观察大量队列,可

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

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

我想让我的工人用户不可知(即,任何工人都应该能够处理任何用户的工作)。这将帮助我水平缩放

我该怎么做呢?我曾考虑过为每个用户创建单独的队列,但这样一来,工作人员将不得不观察大量队列,可能会浪费资源。我现在正在使用beanstalkd作为队列服务器


感谢您的帮助

首先,我要说的是,限制每个用户只处理一个作业可能会导致其他用户处理作业的极端延迟。考虑一个场景,当您的队列包含USER1的大量连续作业数之后,为USER2提供大量连续的作业数等等。由于您提出的体系结构,您必须首先排空user1作业队列,然后才开始处理user2作业,让user3等待很长时间

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

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

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