2013-03-06 29 views
5

Tôi muốn triển khai hệ thống thực hiện công việc phân tán bằng cần tây. Cho rằng rabbitMQ không hỗ trợ các ưu tiên và tôi rất cần tính năng này, tôi đã chuyển sang cần tây + redis.Ưu tiên nhiệm vụ trong cần tây với redis

Trong trường hợp của tôi, các tác vụ liên quan chặt chẽ đến phần cứng, ví dụ, tác vụ A chỉ có thể chạy trên Worker 1 vì chỉ PC của Worker 1 mới có phần cứng cần thiết. Tôi đặt CONCURRENCY của mỗi nhân viên thành 1 để một nhân viên sẽ chỉ thực hiện một nhiệm vụ mỗi lần. Mỗi tác vụ mất khoảng 2 phút.

Để thực hiện các tính năng ưu tiên, trước hết tôi đã cố gắng thêm priority tranh cãi khi gọi apply_async(), ví dụ apply_async(priority=0)apply_async(priority=9). Trong bài kiểm tra này, tôi chỉ khởi chạy một Worker với COCURRENCY = 1 và khởi động 10 tác vụ một với các ưu tiên khác nhau. Tôi dự kiến ​​sẽ thấy các nhiệm vụ được khởi động bởi apply_async(priority=0) sẽ chạy ở mức độ ưu tiên, nhưng tiếc là chúng chỉ được bắt đầu là thứ tự khởi động.

Sau đó, tôi cố gắng thực hiện một số công việc xung quanh. Tôi nhân bản từng tác vụ, vì vậy đối với mỗi tác vụ tôi có task_high và task_low, được trang trí bởi @celery.task(priority=0)@celery.task(priority=1). Sau đó, tôi đã làm thử nghiệm tương tự như trên, lần này nó tốt hơn, khi lệnh khởi động là "HH-LLLL-HHHH", thứ tự thực sự xuất hiện là "HH-L-H-H-L-H-L-L-H". Tôi cho rằng redis đã làm một số công việc lập kế hoạch và cân bằng ở đây.

Nhưng điều này vẫn không thể đáp ứng được kỳ vọng của tôi. Tôi hy vọng sẽ nhận được một đơn đặt hàng như "HHHHHH-LLLL", bởi vì đối với một số nhiệm vụ tôi chỉ có một máy phù hợp với phần cứng cần thiết và hy vọng nhiệm vụ có mức độ ưu tiên cao sẽ chạy càng sớm càng tốt.

Tôi đã tìm kiếm công việc khác trên Internet, ví dụ như sử dụng hai hàng đợi, một cho các tác vụ có mức ưu tiên cao và một cho ưu tiên thấp và sử dụng 2 máy cho máy cũ và 1 cho máy sau. Nhưng kể từ khi phần cứng của tôi là khá hạn chế, điều này không làm việc cho tôi.

Bạn có thể đưa ra một số đề xuất không?

Trả lời

13

Phương tiện vận chuyển cần cẩu đỏ không tôn trọng trường ưu tiên, nhưng bản thân Redis không có khái niệm ưu tiên.

Hỗ trợ ưu tiên được triển khai bằng cách tạo danh sách n cho mỗi hàng đợi và sử dụng thứ tự đó trong lệnh BRPOP. Tôi nói n ở đây vì mặc dù có 10 (0-9) mức độ ưu tiên, đây là được hợp nhất thành 4 cấp theo mặc định để tiết kiệm tài nguyên. Điều này có nghĩa rằng một hàng đợi tên celery sẽ thực sự được chia thành 4 hàng đợi:

['celery0', 'celery3`, `celery6`, `celery9`] 

Nếu bạn muốn mức ưu tiên hơn bạn có thể thiết lập các tùy chọn priority_steps vận chuyển:

BROKER_TRANSPORT_OPTIONS = { 
    'priority_steps': list(range(10)), 
} 

Điều đó nói rằng, lưu ý rằng đây sẽ không bao giờ tốt bằng các ưu tiên được triển khai ở cấp máy chủ và có thể là gần đúng nhất. Nhưng nó vẫn có thể là tốt đủ cho ứng dụng của bạn.

+0

Cảm ơn bạn đã biết chi tiết, nhưng tôi có thể làm gì để nhận được đơn đặt hàng như tôi muốn? Tôi có nên thay đổi 'priority_steps' không? –

+0

Bạn sẽ chỉ dùng thử. Với các bước ưu tiên mặc định, các bước 0 và 1 sẽ được hợp nhất thành 0 chỉ. – asksol

+0

OK cảm ơn, tôi đã thử với ưu tiên 0 cho nhiệm vụ cao và ưu tiên 9 cho nhiệm vụ thấp, bây giờ có vẻ tốt hơn nhiều, mặc dù đôi khi một số nhiệm vụ có ưu tiên 9 vẫn chạy trước ưu tiên 0. Tôi không biết có gì không sai với cấu hình của tôi hoặc redis đã làm một số công việc cân bằng. –