Przydatność wzoru ZeroMQ / ZMQ Push / Pull

W eksperymentowaniu z ZeroMQ Push/Pull (to, co nazywają Pipeline) typu gniazda, mam trudności ze zrozumieniem użyteczności tego wzoru. Jest rozliczany jako "load-balancer".

Biorąc pod uwagę pojedynczy serwer wysyłający zadania do wielu pracowników, Push / Pull równomiernie rozdaje zadania między wszystkimi klientami. 3 klientów i 30 zadań, każdy klient dostaje 10 zadań: KLIENT1 dostaje zadania 1, 4, 7,... klient2, 2, 5,.. i tak dalej. W porządku. Dosłownie.

Jednak w praktyce tam często jest niejednorodną mieszanką złożoności zadań lub zasobów obliczeniowych klienta( lub dostępności), wtedy ten wzór łamie się źle. Wszystkie zadania wydają się być zaplanowane z wyprzedzeniem, a serwer nie ma wiedzy o postępach klientów lub czy są one w ogóle dostępne. Jeśli Client1 upadnie, jego pozostałe zadania nie są wysyłane do innych klientów, ale pozostają w kolejce do client1. Jeśli KLIENT1 pozostaje w dół, to te zadania nigdy nie są obsługiwane. Odwrotnie, jeśli klient jest szybszy w przetwarzaniu jego zadania, nie otrzymuje kolejnych zadań i pozostaje bezczynny, ponieważ pozostają zaplanowane dla innych klientów.

Użycie REQ/REP jest jednym z możliwych rozwiązań; zadania są wtedy przekazywane tylko dostępnemu zasobowi .

Czy coś przeoczyłem? Jak skutecznie stosować Push/Pull? Czy jest sposób, aby poradzić sobie z asymetrią klientów, zadań itp. z tego typu gniazdami?

Dzięki!

Oto prosty przykład Pythona:

# server

import zmq
import time

context = zmq.Context()
socket = context.socket(zmq.PUSH)
#socket = context.socket(zmq.REP)   # uncomment for Req/Rep

socket.bind("tcp://127.0.0.1:5555")

i = 0
time.sleep(1)   # naive wait for clients to arrive

while True:
  #msg = socket.recv()    # uncomment for Req/Rep
  socket.send(chr(i))
  i += 1 
  if i == 100:
    break

time.sleep(10)   # naive wait for tasks to drain

.

# client

import zmq
import time
import sys

context = zmq.Context()

socket = context.socket(zmq.PULL)
#socket = context.socket(zmq.REQ)    # uncomment for Req/Rep

socket.connect("tcp://127.0.0.1:5555")

delay = float(sys.argv[1])

while True:
  #socket.send('')     # uncomment for Req/Rep
  message = socket.recv()
  print "recv:", ord(message)
  time.sleep(delay)

Odpal 3 klientów z parametr delay w wierszu poleceń (ie, 1, 1 i 0.1), a następnie na serwerze, i zobaczyć, jak wszystkie zadania są równomiernie rozłożone. Następnie Zabij jednego z klientów, aby zobaczyć, że jego pozostałe zadania nie są obsługiwane.

Odkomentuj wskazane linie, aby przełączyć je na gniazdo typu Req/Rep i obserwować bardziej efektywny load-balancer.

Author: Benyamin Jafari, 2012-09-20

1 answers

To nie jest load balancer, to było błędne Wyjaśnienie, które przez jakiś czas pozostawało w dokumentach 0MQ. Aby wykonać równoważenie obciążenia, musisz uzyskać informacje od pracowników o ich dostępności. PUSH, podobnie jak DEALER, jest dystrybutorem round-robin. Jest przydatny ze względu na szybkość i prostotę. Nie potrzebujesz żadnych rozmów, po prostu pompuj zadania w dół rurociągu i są rozpylane do wszystkich dostępnych pracowników tak szybko, jak sieć może sobie z nimi poradzić.

Wzór jest przydatny kiedy wykonujesz naprawdę dużą liczbę małych zadań i gdzie pracownicy przychodzą i odchodzą rzadko. Wzorzec nie jest dobry dla większych zadań, które wymagają czasu, ponieważ wtedy potrzebna jest pojedyncza kolejka, która wysyła nowe zadania tylko do dostępnych pracowników. Cierpi również na anty-wzorzec, w którym jeśli klient wysyła wiele zadań, a następnie pracownicy łączą się, pierwszy pracownik przechwyci około 1000 wiadomości, podczas gdy inni nadal są zajęci łączeniem.

Możesz zrobić własny routing wyższego poziomu w na kilka sposobów. Spójrz na wzorce LRU w Przewodniku: w tym pracownicy wyraźnie mówią brokerowi "gotowy". Możesz również kontrolować przepływ oparty na kredytach, a to jest to, co bym zrobił w każdej rzeczywistej sytuacji równoważenia obciążenia. To uogólnienie wzoru LRU. Zobacz http://hintjens.com/blog:15

 51
Author: Pieter Hintjens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-12 23:05:17