System Design

Backpressure: khi producer nhanh gấp 3, làm sao queue không tràn?

Tóm tắt

Backpressure là cơ chế để phía nhận báo ngược cho phía gửi “chậm lại”. Buffer có ngưỡng trên (high watermark) để phát tín hiệu PAUSE và ngưỡng dưới (low watermark) để phát RESUME. Nhờ vậy queue không tràn và cả hệ thống chạy đúng tốc độ của consumer.

Xem trên Facebook

Producer sinh dữ liệu nhanh gấp ba consumer. Điều gì xảy ra với hàng đợi ở giữa? Nếu không có gì can thiệp, nó phình ra đến khi tràn bộ nhớ (OOM) hoặc độ trễ tăng vô hạn. Backpressure là cơ chế để phía nhận báo ngược cho phía gửi “chậm lại”. Một cách cài đặt phổ biến dùng hai ngưỡng: high watermark để phát tín hiệu PAUSE và low watermark để phát RESUME.

Cơ chế watermark (buffer 8 chỗ)

MốcĐiều xảy ra
Chạm high watermark 6/8Tín hiệu PAUSE gửi ngược lên producer.
Lên đỉnh 7/82 message đang bay vẫn tới nơi — ngưỡng đặt dưới sức chứa chính là để hấp thụ phần này.
Tụt về low watermark 2/8Tín hiệu RESUME, producer gửi tiếp.

Producer nhanh gấp 3 cũng không kéo throughput lên: hệ thống luôn chạy đúng 1 msg/s của consumer.

Vì sao cần hai ngưỡng?

  • Nếu chỉ có một ngưỡng, producer sẽ liên tục dừng–chạy–dừng quanh đúng điểm đó (flapping).
  • Khoảng cách giữa hai ngưỡng tạo độ trễ (hysteresis) để chuyển trạng thái ổn định.
  • Ngưỡng cao đặt dưới sức chứa để chừa chỗ cho message đang trên đường tới.

Các chiến lược khi hàng đợi đầy

Chiến lượcHành viPhù hợp khi
Chặn producer (backpressure)Producer đợi tới khi có chỗKhông được mất dữ liệu
Bỏ bớt (drop/sample)Loại message cũ hoặc mớiDữ liệu thời gian thực, chấp nhận mất (telemetry, vị trí)
Từ chối (429)Trả lỗi cho client để thử lại sauAPI công khai, kiểm soát tải ở biên
Mở rộng consumerThêm tài nguyên xử lýTải tăng thường xuyên

Có sẵn trong nhiều công cụ

  • Node.js streams: highWaterMark và sự kiện drain.
  • Reactive Streams, RxJS: yêu cầu số phần tử mong muốn.
  • TCP flow control: cửa sổ nhận.
  • Kafka: theo dõi consumer lag để biết consumer có theo kịp không.

Áp dụng thế nào?

  • Đừng dùng queue không giới hạn trong code production — đó là cách nhanh nhất dẫn tới OOM.
  • Chọn chiến lược khi đầy theo bản chất dữ liệu: chặn, bỏ hay trả lỗi.
  • Giải quyết tận gốc: nếu producer luôn nhanh hơn, cần scale consumer; backpressure chỉ giữ hệ thống không sập.
  • Giám sát: độ sâu hàng đợi và thời gian chờ là chỉ số sớm của quá tải.

Nguồn & tham khảo

  1. Backpressuring in Streams — Node.js