2015-05-16 16 views
8

Tôi tự hỏi liệu có cách nào để thiết lập RabbitMQ hoặc Redis để làm việc với Celery để khi tôi gửi một nhiệm vụ đến hàng đợi, nó không đi vào một danh sách các nhiệm vụ, mà là vào một tập hợp các nhiệm vụ được khóa dựa trên tải trọng nhiệm vụ của tôi, để tránh trùng lặp.Hàng đợi nhiệm vụ phân tán Dựa trên các bộ như cấu trúc dữ liệu thay vì danh sách

Đây là thiết lập của tôi để biết thêm ngữ cảnh: Python + Cần tây. Tôi đã dùng thử RabbitMQ làm phụ trợ, giờ tôi đang sử dụng Redis làm phụ trợ vì tôi không cần độ tin cậy 100%, dễ sử dụng hơn, dấu chân bộ nhớ nhỏ, v.v.

Tôi có khoảng 1000 id cần làm việc liên tục. Giai đoạn 1 của đường dẫn dữ liệu của tôi được kích hoạt bởi một trình lên lịch và nó xuất ra các nhiệm vụ cho giai đoạn 2. Nhiệm vụ chỉ chứa id mà công việc cần được thực hiện và dữ liệu thực được lưu trữ trong cơ sở dữ liệu. Tôi có thể chạy bất kỳ kết hợp hoặc chuỗi các giai đoạn 1 và nhiệm vụ giai đoạn 2 mà không gây hại.

Nếu giai đoạn 2 không có đủ sức mạnh xử lý để xử lý khối lượng công việc đầu ra theo giai đoạn 1, hàng đợi nhiệm vụ của tôi tăng và tăng. Điều này sẽ không phải là trường hợp nếu hàng đợi nhiệm vụ được sử dụng đặt làm cấu trúc dữ liệu cơ bản thay vì danh sách.

Có giải pháp off-the-shelf để chuyển từ danh sách thành tập hợp dưới dạng hàng đợi công việc được phân phối không? Celery có khả năng này không? Gần đây tôi đã thấy rằng Redis vừa phát hành một phiên bản alpha của một hệ thống xếp hàng, vì vậy chưa sẵn sàng để sử dụng sản xuất.

Tôi có nên kiến ​​trúc sư cho đường ống của mình theo cách khác không?

+1

Với RabbitMQ, bạn có thể tạo một hàng đợi cho mỗi ID duy nhất với độ sâu hàng đợi tối đa ('x-max-length') là 1. Có thêm dịch vụ dọn dẹp xuất bản và đăng ký 1000 hàng đợi khác nhau, nhưng các bản sao sẽ bị loại bỏ theo yêu cầu của bạn. – tariksbl

+0

Đây chính xác là loại kiểu workaround logic mà tôi đang tìm kiếm, nhưng giải pháp đặc biệt này có vẻ tẻ nhạt và tôi cũng muốn tránh xa RabbitMQ về sau. Tuy nhiên, cảm ơn bạn vì sự sáng tạo! – Heliodor

Trả lời

1

Nhiệm vụ của bạn trong giai đoạn 2 có thể kiểm tra xem tác phẩm đã được thực hiện chưa và nếu có, sau đó không thực hiện lại công việc? Bằng cách đó, mặc dù danh sách nhiệm vụ của bạn sẽ tăng lên, số lượng công việc bạn cần làm sẽ không.

Tôi đã không đi qua một giải pháp lại các bộ/danh sách, và tôi nghĩ rằng có rất nhiều cách khác để giải quyết vấn đề này.

+0

Kích thước của hàng đợi nhiệm vụ chính là vấn đề. Tùy thuộc vào phần mềm nào bạn sử dụng làm giải pháp xếp hàng, bạn có thể sẽ chiếm bộ nhớ hoặc chiếm không gian trong cơ sở dữ liệu. Không ai trong số đó là mong muốn. Tôi thích một hệ thống tốt. – Heliodor

+0

Phải, tôi hiểu. Có lẽ ngay cả khi bạn đã có giải pháp bằng cách sử dụng bộ, bạn muốn xếp hàng công việc đã được hoàn thành? Tôi tự hỏi nếu có một cách để ghi âm "Làm việc được thực hiện hoặc lập kế hoạch để được thực hiện" một nơi nào đó, và chỉ thêm nhiệm vụ vào hàng đợi nếu nó không có trong danh sách đó. – Maximilian

-1

Sử dụng SortedSet trong Redis cho hàng đợi công việc của bạn. Nó thực sự là một Set vì vậy nếu bạn đặt chính xác cùng một dữ liệu bên trong nó sẽ không thêm một giá trị mới trong nó (nó hoàn toàn cần phải là cùng một dữ liệu chính xác, bạn không thể ghi đè lên hàm băm được sử dụng trong SortedSet trong Redis).

Bạn sẽ cần điểm số để sử dụng với SortedSet, bạn có thể sử dụng dấu thời gian (giá trị gấp đôi, sử dụng unixtime chẳng hạn) sẽ cho phép bạn nhận các mục/mục cũ nhất gần đây nhất nếu bạn muốn. ZRANGEBYSCORE có lẽ là lệnh bạn sẽ tìm kiếm. http://redis.io/commands/zrangebyscore

Hơn nữa, nếu bạn cần thêm hành vi, bạn có thể bao bọc mọi thứ bên trong Lua Script cho hành vi nguyên tử và chiến lược loại bỏ tùy chỉnh nếu cần. Ví dụ, gọi một tập lệnh "get" nhận lệnh in và xóa nó khỏi hàng đợi một cách nguyên tử hoặc mô tả dữ liệu nếu có quá nhiều áp lực trở lại, v.v.

+0

Đã bỏ phiếu. OP đã biết rằng các bộ hoặc các bộ sắp xếp sẽ giải quyết các vấn đề. Những gì OP được hỏi là bộ/bộ được sắp xếp có thể dễ dàng cắm vào Celery hay không. – DhruvPathak

2

Bạn có thể sử dụng cấu trúc dữ liệu ngoài để lưu trữ và theo dõi trạng thái hiện tại của hàng cần tây của bạn. 1. Cho phép lấy một khóa-giá trị redis ví dụ. Bất cứ khi nào bạn đẩy một nhiệm vụ vào cần tây, bạn đánh dấu một khóa với trường 'id' của bạn là true trong redis.

  1. Trước khi cố gắng đẩy tác vụ mới bằng bất kỳ 'id' nào, bạn sẽ kiểm tra xem khóa có 'id' có đúng là redis hay không, nếu có, bạn bỏ qua đẩy nhiệm vụ.

  2. Để xóa các phím vào đúng thời điểm, bạn có thể sử dụng after_return bộ xử lý cần tây, chạy khi nhiệm vụ được trả về.Trình xử lý này sẽ bỏ đặt khóa 'id' trong redis, do đó xóa khóa cho thao tác đẩy tiếp theo.

Phương pháp này đảm bảo bạn chỉ có ONE bản sao cho mỗi tác vụ chạy trong hàng đợi cần tây. Bạn cũng có thể tăng cường nó để chỉ cho phép N nhiệm vụ trên mỗi id bằng cách sử dụng lệnh INCR và DECR trên khóa redis, khi nhiệm vụ được đẩy và sau khi trả về nhiệm vụ.

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