Bỏ qua điều hướng

Khóa họcArchitecture

Thiết kế hệ thống chịu tải cao - rate limiting, load shedding và circuit breaker

Systems under high load: tail latency and fan-out, concurrency limits and connection pool sizing, rate limiting, waiting rooms, load shedding and backpressure, cache keys, invalidation, cache stampede and CDN headers, deadline budgets, bulkheads, circuit breakers and graceful degradation

Fig. 01Thiết kế hệ thống chịu tải cao - rate limiting, load shedding và circuit breaker

Trong khoá học này, bạn thiết kế hệ thống giữ được goodput, tức số request thành công trong deadline, khi tải vượt capacity, key cache hết hạn hay dependency chậm đi. Bạn đặt concurrency limit và rate limit, chọn request bị từ chối bằng load shedding, chống cache stampede, thêm bulkhead và circuit breaker.

  • 20 bài
  • 6h50p
  • 10 quiz
  • 3 bài học thử miễn phí
  • 47 học viên

Bạn sẽ làm được gì

Hệ thống nào cũng có lúc nhận nhiều việc hơn mức nó xử lý kịp, vì tổng tải vượt capacity, vì một client gửi quá nhiều request, vì một key cache hết hạn đúng giờ cao điểm hay vì một dependency chậm đi. Nếu không có cơ chế nào chặn lại, số request thành công trong deadline giảm đúng lúc tải tăng. Bảy kỹ năng dưới đây giúp bạn giữ con số đó ổn định, kể cả khi phải từ chối bớt một phần request.

  1. Tính p99 cho API gọi nhiều service — Với giả định các lời gọi chậm độc lập với nhau, bạn tính được bao nhiêu phần trăm request của API gặp ít nhất một lời gọi chậm, và đọc đúng p99 của service chạy nhiều instance bằng cách gộp histogram thay vì lấy trung bình p99 của từng instance.
  2. Đặt concurrency limit và kích thước pool — Bạn tính hai giá trị này từ Little’s Law và bảng load test, để request vượt mức bị từ chối ngay, hoặc chỉ chờ connection trong service một khoảng thời gian có giới hạn, thay vì xếp hàng cho tới khi quá deadline.
  3. Giới hạn từng client bằng rate limiting — Bạn chọn key để nhận diện client, chọn rate và burst cho token bucket, rồi đặt bộ đếm dùng chung giữa các instance. Với LLM gateway, bạn giới hạn theo số token LLM và tạm giữ trước số token tối đa của mỗi request, vì số token thật chỉ biết được khi LLM provider trả lời.
  4. Chọn request bị từ chối khi quá tải — Khi tổng tải vượt capacity, bạn cho người dùng vào theo lượt bằng waiting room, từ chối trước nhóm request ít quan trọng bằng load shedding, và giới hạn hàng chờ trong RAM bằng backpressure.
  5. Thiết kế cache cho giờ cao điểm — Bạn đặt cache key, chọn TTL riêng cho từng loại dữ liệu theo mức độ cũ mà sản phẩm chấp nhận được, chặn giá trị cũ quay lại cache sau khi dữ liệu đổi, chống cache stampede khi một key bị hết hạn trong lúc đang nhận hàng nghìn lượt đọc mỗi giây, và viết Cache-Control cho từng loại nội dung trên CDN.
  6. Cô lập dependency chậm hoặc lỗi — Bạn chia deadline cho request đi qua nhiều service, tách pool riêng bằng bulkhead, chọn ngưỡng cho circuit breaker và lên sẵn các mức giảm chức năng để luồng quan trọng vẫn chạy.
  7. Chẩn đoán p99 cao khi CPU thấp — Từ panel p99, bạn lần qua trace và metric của pool để tìm dependency đang giữ hết tài nguyên, dù tỉ lệ lỗi và CPU vẫn ở mức bình thường.

Các tham số như limit, TTL, ngưỡng hay kích thước pool được chọn từ số liệu đo trên hệ thống của bạn, cùng với requirement của sản phẩm như dữ liệu được phép cũ bao lâu hay một job được phép chạy lâu tới đâu, nên cách chọn không gắn với một ngôn ngữ hay hạ tầng cụ thể nào.

Xem bản Markdown

Bạn có đang gặp những dấu hiệu này?

  • Tải tăng từ 950 lên 1.050 request/giây, chỉ vượt capacity 5%, mà p99 tăng từ 400 ms lên khoảng 6 giây và hơn nửa số request trễ deadlineKhi utilization tiến gần 100%, thời gian chờ trong hàng tăng rất nhanh, mà service lại không có concurrency limit nên mọi request nó nhận đều chậm theo.
  • Load test với tổng kích thước connection pool tăng từ 48 lên 320 cho pool_wait về 0, nhưng p99 truy vấn lại tăng và CPU Postgres tăng lên 97%Hàng chờ chỉ chuyển từ service vào trong database, nơi quá nhiều truy vấn cùng giành CPU.
  • Load balancer loại lần lượt cả sáu instance catalog trong 25 giây dù chưa instance nào chếtHealth check phải xếp hàng sau request thường nên quá timeout, và mỗi instance bị loại lại dồn thêm tải cho các instance còn lại.
Xem đủ 8 dấu hiệu và vì sao có khóa học này

Khóa học này có hợp với bạn?

Khoá học dành cho ai

  1. Developer backend vận hành servicePhù hợp nhất— API của bạn đang chạy trên production và p99 từng vọt lên vào giờ cao điểm; bạn cần biết nên đặt limit, pool, TTL hay timeout ở mức nào thay vì tăng dần cho tới khi hết lỗi.
  2. Người phụ trách API công khai hoặc gateway— Đối tác, khách hàng hay script bên ngoài gọi vào API của bạn, có khi qua một gateway chuyển tiếp lên LLM provider, và bạn cần giới hạn từng client mà không chặn nhầm người dùng thật.
  3. Người chuẩn bị cho đợt sale hay mở bán— Trước một đợt tải lớn đã lên lịch, bạn là người quyết định request nào được vào, request nào bị từ chối và chức năng nào được giảm bớt, rồi giải thích quyết định đó với cả team.

Những điều cần lưu ý

  1. Cần có kiến thức nền về tải và timeout — Bạn cần biết trước phần ước lượng tải: Little’s Law, headroom, p99, SLO, lúc nào cần thêm cache hay queue, cách tìm bottleneck và cách lỗi lan ra qua tài nguyên dùng chung. Bạn cũng cần biết trước phần xử lý timeout: cách đọc timeline của hai request chạy song song, deadline, phân loại lỗi trước khi retry, backoff, jitter và retry budget. Riêng vài bài tình huống còn dùng lại idempotency key, lease, checkpoint và thao tác cập nhật atomic có điều kiện. Mỗi kiến thức này chỉ được nhắc lại một câu, nên từng bài dành trọn cho cơ chế mới.
  2. Không gồm failover hay autoscaling — Failover khi mất máy, backup, autoscaling và cách cấu hình nginx, Envoy hay một thư viện circuit breaker cụ thể không có trong khoá học; bạn hiểu cơ chế đủ để biết mỗi tham số của công cụ ứng với quyết định nào và nên đặt nó bằng số liệu nào.
  3. Số liệu trong ví dụ do bài tự đặt — Capacity của checkout, hạn mức token của LLM provider hay tốc độ ghi của Postgres trong các bài được chọn để các phép tính khớp nhau, không phải giới hạn thật của bất kỳ công cụ hay provider nào; khi áp dụng, bạn chạy load test để có số của riêng mình rồi đưa vào cùng phép tính.

Bạn sẽ học theo cách nào

  1. Đọc dashboard như kỹ sư trực— Phần đầu mỗi bài đặt bạn vào vị trí của kỹ sư trực, với một panel p99 đang đỏ, một đoạn log hay một trace từ hệ thống trong ví dụ, và câu hỏi chuyện gì đang xảy ra.
  2. Hàng chờ và pool được vẽ ra— Nhìn ảnh hay sơ đồ gọn của mỗi bài, bạn thấy request đang xếp hàng ở đâu, pool nào bị giữ và cơ chế mới đứng ở vị trí nào trên đường đi của request. Little’s Law hay xác suất gặp lời gọi chậm được viết ra từng bước, kèm đơn vị.
  3. Một tham số chọn bằng số liệu— Bài cơ chế nào cũng chọn một tham số như limit, TTL, ngưỡng hay kích thước pool từ số liệu và requirement của ví dụ, nói rõ tradeoff, và chỉ ra ở quy mô nào hệ thống chưa cần cơ chế đó.
  4. Quiz yêu cầu bạn dự đoán— Phần lớn bài cơ chế có quiz ngắn, với những câu như đoán p99 sau khi đổi số lời gọi hay đoán circuit breaker chuyển sang open vào lúc nào.
  5. Bốn demo kit chạy bằng Docker— Kit của mỗi bài tình huống là một file Markdown cho coding agent của bạn: agent dựng hệ thống ở trạng thái “trước”, chạy một mức tải cố định để triệu chứng hiện ra, rồi sau khi bạn tự sửa theo bài thì chạy lại và báo kết quả từng tiêu chí trước và sau khi sửa. Kit không chứa lời giải và không bắt buộc.

Mentor

Bắt đầu từ đâu

Khoá học bắt đầu từ bảy phút đầu của một đêm sale: số request đổ vào tăng gấp ba, còn số request thành công trong deadline (goodput) tụt từ 2.000 xuống 700 request/giây. Câu hỏi đầu tiên nghe có vẻ ngược: nếu chỉ nhận đúng 3.000 request/giây mà hệ thống xử lý kịp và từ chối nhanh phần còn lại, goodput sẽ tăng hay giảm? Phép tính cho thấy goodput tăng tối đa khoảng 4,3 lần, lên 3.000 request/giây. Mức trần đó chỉ đạt được khi cache stampede và tình trạng dependency chậm giữ hết pool cũng được xử lý, nên bốn nhóm cơ chế phải đi cùng nhau.

Học thử bài đầu tiên