thắc mắc [Hỏi đáp] Xin tư vấn kiến trúc RabbitMQ giải quyết bài toán Load-balancing / Tenant Fairness (tránh tình trạng 1 user spam làm tắc nghẽn user khác).

  • Người tạo chủ đề Người tạo chủ đề ZillBee
  • Ngày bắt đầu Ngày bắt đầu

ZillBee

Junior Member
Chào mọi người, Hệ thống web của em có chức năng cho phép user nhập URL sản phẩm để xử lý. Quá trình này gồm nhiều bước mất thời gian nên em chia nhỏ thành các bước, viết các Worker riêng và dùng RabbitMQ để push/consume message giữa các bước.

Em đang gặp một bài toán về Load-Balancing và đảm bảo tính công bằng (Fairness): Làm sao để tránh tình trạng User A push 1000 URLs làm nghẽn hệ thống, khiến User B push 1 URL sau đó phải chờ rất lâu mới được xử lý?

Hiện tại, em đang giải quyết bằng cách: Tạo cho mỗi user 1 queue riêng (ví dụ: queue.crawl.user-{userId}). Trong Worker, em lấy danh sách các queue này và BasicConsume tất cả trên cùng một channel.

Tuy nhiên, cách này đang gặp vấn đề:

  1. Nếu em cấu hình prefetchCount = 1 (để worker lấy lần lượt mỗi queue 1 message, đảm bảo công bằng) thì throughput (hiệu suất) rất thấp, xử lý chậm do overhead mạng của việc ack/fetch từng message.
  2. Nếu em tăng prefetchCount cao hơn để tối ưu hiệu suất, thì worker lại gom một loạt message của User A (nếu queue của A đang dài), dẫn đến phá vỡ tính công bằng, User B vẫn bị "đói" (starvation).
  3. Nếu hệ thống có số lượng user lớn (ví dụ 10.000 users) thì việc maintain 10.000 queues liên tục có vẻ không ổn về mặt resource.
Mọi người cho em hỏi với bài toán Fair-processing / Multi-tenant queuing như thế này thì:

  • Cách mỗi user 1 queue như em làm có phải là best practice không ạ?
  • Có design pattern, plugin nào của RabbitMQ phù hợp để giải quyết trọn vẹn bài toán: Vừa đảm bảo throughput cao, vừa đảm bảo tính công bằng (Fairness) giữa các user không ạ?
Em cảm ơn mọi người!
 
Theo mình thấy thì bạn có thể thử scale consumer theo từng queue. Vdu queue A có 10k messages thì có N consumer, queue B có 1k messages thì có M consumer. Mỗi consumer sẽ fetch message theo queue được chỉ định thôi. Cách này thì mình có thể đảm bảo throughput cũng như tránh tình trạng một queue bị ngẽn kéo theo user khác cũng bị ảnh hưởng
 
Chào mọi người, Hệ thống web của em có chức năng cho phép user nhập URL sản phẩm để xử lý. Quá trình này gồm nhiều bước mất thời gian nên em chia nhỏ thành các bước, viết các Worker riêng và dùng RabbitMQ để push/consume message giữa các bước.

Em đang gặp một bài toán về Load-Balancing và đảm bảo tính công bằng (Fairness): Làm sao để tránh tình trạng User A push 1000 URLs làm nghẽn hệ thống, khiến User B push 1 URL sau đó phải chờ rất lâu mới được xử lý?

Hiện tại, em đang giải quyết bằng cách: Tạo cho mỗi user 1 queue riêng (ví dụ: queue.crawl.user-{userId}). Trong Worker, em lấy danh sách các queue này và BasicConsume tất cả trên cùng một channel.

Tuy nhiên, cách này đang gặp vấn đề:

  1. Nếu em cấu hình prefetchCount = 1 (để worker lấy lần lượt mỗi queue 1 message, đảm bảo công bằng) thì throughput (hiệu suất) rất thấp, xử lý chậm do overhead mạng của việc ack/fetch từng message.
  2. Nếu em tăng prefetchCount cao hơn để tối ưu hiệu suất, thì worker lại gom một loạt message của User A (nếu queue của A đang dài), dẫn đến phá vỡ tính công bằng, User B vẫn bị "đói" (starvation).
  3. Nếu hệ thống có số lượng user lớn (ví dụ 10.000 users) thì việc maintain 10.000 queues liên tục có vẻ không ổn về mặt resource.
Mọi người cho em hỏi với bài toán Fair-processing / Multi-tenant queuing như thế này thì:

  • Cách mỗi user 1 queue như em làm có phải là best practice không ạ?
  • Có design pattern, plugin nào của RabbitMQ phù hợp để giải quyết trọn vẹn bài toán: Vừa đảm bảo throughput cao, vừa đảm bảo tính công bằng (Fairness) giữa các user không ạ?
Em cảm ơn mọi người!

sao k hash thay vì mỗi user 1 queue riêng vậy bác, lúc này queue scale theo user thì resource sẽ lãng phí

còn chỗ fairness thì chỗ thằng scheduler bác rate limit dùng token bucket của Redis em thấy hợp lý cho use case này

via theNEXTvoz for iPhone
 
RabbitMQ có support priority đấy, bạn chỉ cần dùng 1 queue nhưng đánh priority cho message khác nhau (vd message đầu tiên của user đc ưu tiên priority cao nhất, rồi giảm dần từ từ về zero)
Tuy nhiên priority này là fetching priority chứ ko phải processing priority nhé.
 

Thống kê chủ đề

Ngày tạo
ZillBee,
Người trả lời cuối
galaxydance,
Trả lời
4
Lượt xem
988
Quay lại
Lên đầu trang