2012-09-20 18 views
34

Khi thử nghiệm với các loại ổ cắm ZeroMQPush/Pull (cái mà chúng gọi là Pipeline), tôi gặp khó khăn khi hiểu tiện ích của mẫu này. Nó được lập hóa đơn như một "cân bằng tải".ZeroMQ Đẩy/kéo mẫu hữu dụng

Với một máy chủ đơn gửi nhiệm vụ cho một số công nhân, Push/Pull sẽ đồng đều phân phát nhiệm vụ giữa tất cả khách hàng. 3 khách hàng và 30 nhiệm vụ, mỗi khách hàng nhận được 10 nhiệm vụ: client1 nhận nhiệm vụ 1, 4, 7, ... client2, 2, 5, ... v.v. Đủ công bằng. Theo nghĩa đen.

Tuy nhiên, trong thực tế, thường có sự kết hợp không đồng nhất của tác vụ phức tạp hoặc tài nguyên tính toán của khách hàng (hoặc tính khả dụng), sau đó mẫu này bị hỏng. Tất cả các nhiệm vụ dường như được lên lịch trước và máy chủ không có kiến ​​thức về tiến độ của khách hàng hoặc nếu chúng thậm chí có sẵn. Nếu client1 đi xuống, các tác vụ còn lại của nó sẽ không được gửi tới các máy khách khác, nhưng vẫn được xếp hàng đợi cho client1. Nếu client1 vẫn còn, thì những nhiệm vụ đó sẽ không bao giờ được xử lý. Ngược lại, nếu một khách hàng xử lý các nhiệm vụ của mình nhanh hơn, nó sẽ không nhận thêm các tác vụ và vẫn còn nhàn rỗi, vì chúng vẫn được lên lịch cho các máy khách khác.

Sử dụng REQ/REP là một giải pháp khả thi; các nhiệm vụ sau đó chỉ được cung cấp cho một tài nguyên có sẵn.

Vì vậy, tôi có thiếu thứ gì đó không? Push/Pull được sử dụng hiệu quả như thế nào? Có cách nào để xử lý sự bất đối xứng của khách hàng, nhiệm vụ, vv, với loại ổ cắm này không?

Cảm ơn!

Dưới đây là một ví dụ Python đơn giản:

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

cháy lên 3 khách hàng với một tham số chậm trễ trên dòng lệnh (tức là, 1, 1, và 0.1) và sau đó máy chủ, và xem như thế nào tất cả các nhiệm vụ được phân bố đều. Sau đó, giết một trong những khách hàng để thấy rằng các nhiệm vụ còn lại của nó không được xử lý.

Bỏ ghi chú các dòng được chỉ định để chuyển sang ổ cắm loại Req/Rep và xem bộ cân bằng tải hiệu quả hơn.

Trả lời

47

Nó không phải là một cân bằng tải, đây là một lời giải thích bị lỗi mà vẫn ở trong tài liệu 0MQ trong một thời gian. Để cân bằng tải, bạn phải lấy lại một số thông tin từ những người lao động về tính khả dụng của họ. PUSH, như DEALER, là một nhà phân phối vòng tròn. Nó rất hữu ích cho tốc độ thô và đơn giản của nó. Bạn không cần bất kỳ loại trò chuyện nào, chỉ cần bơm nhiệm vụ xuống đường ống và chúng được phun ra cho tất cả công nhân có sẵn nhanh như mạng có thể xử lý chúng.

Mẫu này hữu ích khi bạn đang thực hiện số lượng công việc nhỏ thực sự cao và nơi công nhân đến và đi không thường xuyên. Mô hình này không tốt cho các tác vụ lớn hơn cần có thời gian để hoàn thành vì sau đó bạn muốn một hàng đợi duy nhất gửi nhiệm vụ mới chỉ cho các công nhân có sẵn. Nó cũng bị một anti-pattern, nếu một client gửi nhiều nhiệm vụ và sau đó công nhân kết nối, nhân viên đầu tiên sẽ lấy được 1.000 tin nhắn trong khi những người khác vẫn bận rộn kết nối.

Bạn có thể thực hiện định tuyến cấp cao hơn theo nhiều cách. Nhìn vào các mẫu LRU trong Hướng dẫn: trong công việc này, người lao động nói rõ ràng với người môi giới đã sẵn sàng. Bạn cũng có thể kiểm soát dòng chảy dựa trên tín dụng, và đây là những gì tôi muốn làm trong bất kỳ tình huống cân bằng tải thực nào. Đó là sự khái quát về mô hình LRU.Xem http://hintjens.com/blog:15

+0

Khi nhân viên thất bại, có cơ chế nào để phát hiện và khôi phục các tác vụ được xếp hàng đã được giao nhưng không được gửi không? Một cái gì đó giống như một thời gian chờ với một phân phối lại nhiệm vụ. – CNK

+6

Nếu bạn muốn phát hiện người lao động không thành công, bạn phải tự thêm mình. Nó tương đối dễ dàng: thu thập tất cả các kết quả và nếu có một kết quả, hãy khởi động lại toàn bộ lô. Thất bại là đủ hiếm khi cách tiếp cận tàn bạo đơn giản này xử lý nó tốt. –

+2

Vâng, nó vẫn còn trong tài liệu duy trì ở đây: http://zguide.zeromq.org/page:all – easytiger

Các vấn đề liên quan