领导/追随者与工作队列

时间:2011-11-14 09:46:28

标签: design-patterns queue scalability parallel-processing

我刚刚阅读了一篇关于Leader/Follower Pattern的文章,如果我理解正确,我会将我的工作人员留在队列中,第一个工作人员接收传入请求并从队列中分离。

使用正常的工作队列(例如rabbitmqbeanstalkd),反之亦然:我将我的工作保留在队列中,一旦工人完成处理,它就完成了第一份工作从队列中。

有什么东西我不见了?

那么,我应该使用Leader / Follower方法而不是工作队列的优势是什么?或者反过来说,在什么情况下工作队列更适合?

再见 尼科

2 个答案:

答案 0 :(得分:8)

领导/追随者是关于有效地处理多个工人。当你没有工作(工作)时,你的工人或工人在做什么?一种常见的简单方法是通过生成线程或使用线程池将单个使用者线程调度作业分配给工作者。讨论的模式提供了一种替代方法,通过让获得作业的(领导者)线程自己执行工作任务,避免必须在调度程序和工作程序之间进行同步。它促使等待工作者到领导者位置以保持系统响应。

请注意,本文讨论的是等待工作的低级机制,这些机制不(轻松)支持多个线程在同一个“队列”工作上等待。更高级别的构造(如支持多个工作线程的消息队列)都在同一源(AKA竞争消费者)上执行阻塞读取可能无法获得所描述的相同优势。通过更高级别的抽象,可以更轻松地编程,但通常以更低级别方法可以获得的性能为代价。

<强> EDIT1:

这是一个伪造的样本(仅限伪代码)。请注意,我没有写文章或基准测试,所以我无法真正谈论一个与另一个的表现。但希望这表明风格上的差异。

// in QueueHandler processing loop

while(true)
{
   // read, blocking until one arrives
   Request req = requestQueue.BlockingRead();

   // we have a unit of work now but the QueueHandler should not process it
   //  because if it is long running then no new requests can be handled.
   //  so we spawn / dispatch to a thread
   ThreadPool.QueueWorkItem(req);
   // or new Thread(DoWork(), req).Start;

   // at this point we know that the request will get picked up in 
   // an unknown but hopefully very short amount of time by a 
   // waiting (sleeping/blocking) or new thread and it will get passed the 
   // work.  But doing so required the use of thread synchronization 
   // primitives that can cause all processors to flush their caches 
   // and other expensive stuff.


} // now loop back up to read the next request

VS

// in Leader

while(true)
{

   // I'm the leader, blocking read until a request arrives
   Request req = queue.BlockingRead();

   // We have a unit of work and we are going to process it ourselves.  
   // But first we notify a follower.
   Followers.PromoteOne();

   // work on the request in this thread!
   DoWorkOn(req);

   // now that I'm done, wait to the the leader
   Followers.BlockingWaitToBeLeader();

}

答案 1 :(得分:0)

首先,对于工作队列,您需要锁定工作队列。 第二,这是主要问题, 对于工作队列,您必须唤醒工作线程,并且该线程不会处理该工作,直到系统任务调度程序实际运行该任务。 当您使用与填充队列的处理器核心不同的处理器核心处理工作项时,情况会变得更糟。 因此,您可以通过领导者跟随者模式实现更低的延迟。