6

Tôi có một hàng đợi công việc (sử dụng SQS của Amazon) để thực hiện các công việc cho nhiều máy để tìm nạp và xử lý các tài liệu khác nhau qua HTTP. Có hàng trăm máy chủ khác nhau được truy cập và không có thứ tự có thể dự đoán được cho công việc.Phương pháp tự sắp xếp lại hàng đợi công việc

Để lịch sự, tôi không muốn hệ thống của mình liên tục phát trên một máy chủ. Vì vậy, nếu tôi nhận được một công việC# 123 để lấy một cái gì đó từ example.com, nhưng tôi thấy rằng tôi vừa lấy một thứ khác từ example.com trong X giây qua, tôi nên chuyển sang một thứ khác và lưu công việC# 123 cho một lát sau.

Câu hỏi là, cách tốt nhất để triển khai mẫu này là gì?

Dường như bước đầu tiên là để người chạy công việc giữ danh sách ở một nơi nào đó trong tất cả các miền và lần cuối cùng nội dung nào đó trên miền đó được truy cập. Tôi cho rằng đây có thể là một bảng DB đơn giản.

Sau đó, có rất nhiều tùy chọn có thể cho việc cần làm nếu bộ xử lý tin nhắn nhận được lệnh phải hoãn lại.

  1. Chỉ cần đẩy bản sao của thư vào cuối hàng đợi và vứt nó đi mà không cần thực hiện. Hy vọng rằng, vào lần tới nó đến, đủ thời gian sẽ trôi qua. Điều này có thể dẫn đến rất nhiều thông điệp SQS dư thừa, đặc biệt nếu một cụm công việc lớn cho cùng một tên miền đi qua cùng một lúc.

  2. Ngủ trong nhiều giây là cần thiết cho đến khi lịch sự ra lệnh cho công việc có thể được thực thi. Điều này có thể dẫn đến rất nhiều bộ xử lý hàng đợi đồng thời không làm gì cả.

  3. Chấp nhận công việc, nhưng lưu nó vào hàng đợi cục bộ ở đâu đó trên mỗi bộ xử lý hàng đợi. Tôi tưởng tượng mỗi bộ xử lý có thể "tuyên bố" một số công việc theo cách này, và sau đó chọn để xử lý chúng theo thứ tự bất kỳ đạt được sự lịch sự tối đa. Điều này vẫn có thể không đoán trước được, bởi vì mỗi bộ xử lý hàng đợi cần phải nhận thức được các tên miền bị tấn công bởi tất cả những người khác.

  4. Thiết lập hàng đợi riêng cho từng miền và có một quy trình dành riêng cho từng hàng đợi. Mỗi quá trình sẽ phải tạm dừng cho X giây giữa mỗi công việc, vì vậy có rất nhiều quá trình ngủ trên đầu, nhưng có lẽ đây không phải là một điều xấu.

Bạn có kinh nghiệm thiết kế loại điều này không? Bạn sẽ đề xuất chiến lược nào?

+0

Bạn có bị kẹt 100% trên SQS không? Có những thiết kế tốt KHÔNG ép bạn vào giải pháp hàng đợi trên mỗi miền, nhưng chúng yêu cầu bạn phải kiểm soát trực tiếp hàng đợi mà tôi giả định SQS không cung cấp (chính xác, khả năng "duyệt" hàng đợi mà không cần phải lấy phần tử và khả năng lấy phần tử Nth thay vì phần trên - về cơ bản, xử lý hàng đợi là danh sách được liên kết kép mà không chèn và không phải là hàng đợi thuần túy). – DVK

Trả lời

0

Tôi khuyên bạn nên thiết lập hàng đợi cho từng tên miền và một bộ xử lý trên mỗi hàng đợi.

Hầu hết các máy chủ không gặp sự cố với yêu cầu được phát hành liên tục, miễn là bạn để ý đến tổng số lượng chuyển (ví dụ: bạn nên tránh lập chỉ mục các tệp trên hơn vài trăm KB trừ khi bạn có cần cho nó).

Tôi cho rằng bạn cũng tuân thủ các quy tắc robots.txt.

2

Hàng đợi riêng biệt cho từng tên miền và hàng đợi miền.

Mỗi bộ xử lý nên:

  1. Chọn một tên miền từ danh sách các lĩnh vực.
  2. Nếu tên miền không được cập nhật gần đây, hãy chọn tác vụ hàng đầu từ hàng đợi miền.
  3. Đặt miền trở lại vào cuối hàng đợi miền.
  4. Nếu chúng tôi có một nhiệm vụ để thực hiện, hãy thực hiện.
  5. Ngủ cho đến khi đến lúc kiểm tra phần đầu của hàng đợi miền hoặc hàng đợi miền được cập nhật.

Điều này có thể hữu ích nếu bạn sắp xếp hàng đợi các miền dưới dạng hàng đợi ưu tiên theo thời gian - lưu trữ các tên miền theo thứ tự thời gian cập nhật tiếp theo.

+0

Nếu bạn có đủ số lượng miền riêng biệt và bạn dự đoán sự tranh chấp trên hàng đợi tên miền, bạn có thể làm cho nó để các bộ xử lý đặt tên miền trở lại hàng đợi * cục bộ * của riêng chúng. Sau đó, sửa đổi bước 1 thành "Nếu local_queue_size

+0

@j_random_hacker: Không chắc đó là một ý hay. Hàng đợi địa phương làm phức tạp dataflow và lợi ích là đáng ngờ. Nếu bạn không có đủ bộ vi xử lý, hãy thêm nhiều bộ xử lý khác. Nếu hàng đợi tên miền của bạn quá lớn, hãy thêm một số sharding. –

+0

@ Alex: Nếu tôi hiểu ý bạn là "sharding", biến thể dataflow duy nhất mà đề xuất của tôi sẽ giới thiệu - cụ thể là sự trở lại của các tên miền cục bộ quay lại hàng đợi toàn cầu - sẽ xảy ra chính xác. nhàn rỗi. Nó có hiệu quả "tự động sharding" cộng với một cơ chế phục hồi. Tất nhiên bạn có thể bỏ qua cơ chế khôi phục để thực hiện đơn giản hơn, có tất cả các lợi ích (và không hiệu quả) của việc phá hủy mà không cần phải định nghĩa các mảnh trước. –

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