2011-11-14 9 views
9

Właśnie przeczytałem artykuł o Leader/Follower Pattern, a jeśli dobrze zrozumiałem, trzymam moich pracowników w kolejce, a pierwszy pracownik bierze przychodzące żądanie i odłącza się od kolejki.Leader/Follower vs kolejka pracy

W normalnej kolejce pracy (na przykład rabbitmq i beanstalkd) jest odwrotnie: utrzymuję zadania w kolejce i po zakończeniu przetwarzania przez pracownika po prostu pierwsze zadanie z kolejki.

Czy czegoś mi brakuje?

Jakie są zatem zalety, w których powinienem stosować podejście Leader/Follower zamiast kolejki pracy? Lub odwrotnie, w jakich sytuacjach kolejka pracy jest lepiej dopasowana?

Bye, Nico

Odpowiedz

8

Leader/Follower jest o sprawnie do czynienia z wieloma pracownikami. Kiedy nie masz pracy (zadań), co robią twoi pracownicy lub pracownicy? Powszechne, proste podejście polega na tym, że pojedynczy wątek konsumenta wysyła zadania do pracowników, albo poprzez utworzenie wątku, albo użycie puli wątków. Omawiany wzorzec zapewnia alternatywne podejście, które pozwala uniknąć synchronizacji między dyspozytorem a pracownikiem, dzięki temu, że wątek (wiodący), który dostaje zadanie, wykonuje zadanie robocze. Promuje pracownika oczekującego na pozycję lidera, aby system był responsywny.

Należy pamiętać, że ten artykuł omawia mechanizmy niższego poziomu oczekujące na pracę, które nie obsługują wielu wątków oczekujących w tej samej "kolejce" pracy. Konstrukty wyższego poziomu, takie jak kolejki komunikatów, które obsługują wiele wątków roboczych, wszystkie wykonujące blokowanie czytane na tym samym źródle (konkurujący konsumenci AKA) mogą nie uzyskać opisanych korzyści. Przy wyższym poziomie abstrakcji łatwiej jest programować, ale zazwyczaj kosztem tego rodzaju wydajności, którą można uzyskać dzięki bardziej niskopoziomowemu podejściu.

Edit1:

Oto wymyślona próbki (pseudokod tylko). Pamiętaj, że nie napisałem tego artykułu ani nie przetestowałem go, więc nie mogę naprawdę mówić o wydajności jednego z nich. Miejmy nadzieję, że pokazuje różnicę w stylu.

// 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(); 

} 
+0

, więc różnica polega na tym, że to podejście niskiego poziomu nie blokuje i dlatego jest szybsze do wykonania? – Nicolas

+0

Ma mniej rywalizacji, mniej pracy między wątkami. Koordynowanie komunikacji/synchronizacji wątków często wymaga użycia blokad itp., Które mają bardzo negatywny wpływ na kod działający na wielu procesorach. – tcarvin

+0

ale czy możesz wskazać konkretną różnicę między tym a kolejkami pracy? nadal nie mogę zrozumieć, dlaczego kolejki robocze wymagają większego blokowania. – Nicolas

0

Przede wszystkim z kolejki pracy trzeba zamki w kolejkach pracy. Po drugie, i to jest główny problem, z koleją roboczą, musisz obudzić wątek roboczy i ten wątek nie przetworzy pracy, dopóki systemowy harmonogram zadań faktycznie nie uruchomi zadania. Co jest gorsze, gdy przetwarzany jest element pracy z innym rdzeniem procesora niż ten, który wypełnia kolejkę. Dzięki temu można uzyskać znacznie mniejsze opóźnienia z wzorcem naśladowcy lidera.