2012-09-20 3 views
34

ZeroMQPush/Pull (이들은 Pipeline이라고하는 것) 소켓 유형으로 실험 할 때이 패턴의 유용성을 이해하는 데 어려움이 있습니다. 그것은 "로드 밸런서"로 청구됩니다.ZeroMQ 푸시/당기기 패턴 유용성

단일 서버가 여러 작업자에게 작업을 보내면 Push/Pull이 모든 클라이언트 간의 작업을 균등하게 분배합니다. 3 개의 클라이언트와 30 개의 작업을 수행하면 각 클라이언트는 10 개의 작업을 얻습니다. 즉, client1은 작업 1, 4, 7, ... client2, 2, 5, ... 등을 얻습니다. 공정하다. 말 그대로.

그러나 실제로는 작업이 복잡하거나 클라이언트 컴퓨팅 리소스 (또는 가용성)가 비균질적으로 혼합되어있는 경우이 패턴이 잘못됩니다. 모든 작업은 미리 예약 된 것으로 보이며 서버는 클라이언트의 진행 상태 또는 사용 가능한 상태인지 여부를 알지 못합니다. client1이 작동 중지되면 나머지 작업은 다른 클라이언트로 전송되지 않고 client1의 대기열에 남아 있습니다. client1이 계속 작동 중지되면 해당 작업은 절대로 처리되지 않습니다. 반대로, 클라이언트의 작업 처리 속도가 빠르면 더 많은 작업을 수행하지 않고 다른 클라이언트에 대해 일정을 유지하므로 유휴 상태를 유지합니다.

REQ/REP을 사용하는 것이 가능한 솔루션입니다. 작업은 사용 가능한 리소스에만 제공됩니다.

그래서 나는 무엇인가 놓치고 있습니까? Push/Pull은 어떻게 효과적으로 사용됩니까? 이 소켓 유형으로 클라이언트, 작업 등의 비대칭 성을 처리 할 수있는 방법이 있습니까?

감사합니다.

# 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) 

화재 명령 행에서 지연 매개 변수를 최대 3 클라이언트 (즉, 1, 1, 0.1) 후, 서버 및 모든 작업을 균등하게 분배하는 방법을 참조하십시오. 그런 다음 클라이언트 중 하나를 제거하여 나머지 작업이 처리되지 않는지 확인하십시오.

표시된 줄의 주석 처리를 제거하고 Req/Rep 유형 소켓으로 전환하고보다 효과적인 부하 분산 장치를 살펴보십시오.

답변

47

로드 밸런서가 아니기 때문에 오랫동안 0MQ 문서에 머물러있는 잘못된 설명이었습니다. 로드 밸런싱을 수행하려면 작업자의 가용성에 대한 정보를 다시 얻어야합니다. PUSH는 대리점처럼 라운드 로빈 배포자입니다. 원시 속도와 단순성에 유용합니다. 어떤 종류의 잡담도 필요 없으며 파이프 라인을 따라 작업을 펌핑 할뿐 아니라 네트워크가 처리 할 수있는 속도로 모든 사용 가능한 작업자에게 빠르게 분사됩니다.

패턴은 매우 작은 수의 작업을 수행 할 때 유용하며, 작업자가 자주 이동하지 않는 경우 유용합니다. 패턴은 완료하는 데 시간이 오래 걸리는 큰 작업에는 적합하지 않습니다. 새 작업을 사용 가능한 작업자에게만 보내는 단일 큐가 필요하기 때문입니다. 또한 클라이언트가 많은 작업을 보내고 작업자가 연결되면 첫 번째 작업자는 1,000 명 정도의 메시지를 가져오고 다른 작업자는 여전히 연결 중입니다.

여러 가지 방법으로 자신 만의 높은 수준의 라우팅을 만들 수 있습니다. 안내서의 LRU 패턴을 살펴보십시오.이 작업에서 근로자는 브로커에게 '준비'를 명시 적으로 말합니다. 당신은 또한 신용 기반의 흐름 제어를 할 수 있으며 이것은 실제 부하 분산 상황에서해야 할 일입니다. 그것은 LRU 패턴의 일반화입니다.http://hintjens.com/blog:15

+0

작업자가 실패 할 경우 할당 된 있지만 보내지 않은 것보다 대기열에있는 작업을 복구하는 메커니즘이 있습니까? 태스크 재분배를 통한 타임 아웃과 같은 것. – CNK

+6

실패한 작업자를 찾으려면 직접 추가해야합니다. 상대적으로 쉽습니다. 모든 결과를 수집하고 누락 된 것이 있으면 전체 배치를 다시 시작하십시오. 실패는 아주 드물기 때문에이 단순하고 잔인한 접근법으로는 잘 처리됩니다. –

+2

글쎄 아직 여기에 보관 된 문서에 있습니다 : http://zguide.zeromq.org/page:all – easytiger