Requirement, SLO và ước lượng capacity

4 câu hỏi~25 phútTừ khóa: functional, non-functional, SLI, SLO, SLA, availability nines, error budget, back-of-envelope, QPS, peak, storage, bandwidth

Tiếp đi: requirement và ước lượng traffic cho shop-app.

Ở bài trước, ta có khung 45 phút. Bài này đi sâu hai bước đầu: chốt requirement và ước lượng nhanh. Hai bước này quyết định gần như mọi lựa chọn phía sau.

1. Bài toán

Interviewer: "User có thể xem sản phẩm, thêm vào giỏ và checkout. Thiết kế shop-app."

Nếu không hỏi gì, ta không biết shop-app có 100 user hay 10 triệu user, có cần chịu flash sale không, có chấp nhận mất đơn hàng không.

2. Vấn đề

3. Giải pháp: requirement hai loại

LoạiCâu hỏishop-app
FunctionalHệ thống làm gì?1. Xem sản phẩm 2. Thêm vào giỏ 3. Checkout 4. Giữ hàng tồn kho 5. Thanh toán 6. Tạo order 7. Gửi notification
Non-functionalHệ thống làm tốt tới mức nào?High availability, scalable, không trừ tiền 2 lần, không oversell, latency hợp lý, reliable
Out of scopeKhông làm gì (để tiết kiệm thời gian)?Recommendation, review, chat với người bán

Non-functional phải biến thành con số. Đó là việc của SLI/SLO/SLA.

Khái niệmLà gìVí dụ shop-app
SLI (Indicator)Chỉ số đo đượcTỉ lệ request POST /checkout thành công; p99 latency
SLO (Objective)Mục tiêu nội bộ cho SLI99.9% checkout thành công trong 30 ngày; p99 < 800 ms
SLA (Agreement)Cam kết với khách, vi phạm thì có hậu quả (đền tiền)99.5%/tháng, vi phạm hoàn 10% phí

SLA thường lỏng hơn SLO, để còn khoảng đệm trước khi phải đền.

4. Availability "mấy số 9"

AvailabilityDowntime / nămDowntime / tháng (30 ngày)
99%~3.65 ngày~7.2 giờ
99.9%~8.76 giờ~43 phút
99.95%~4.38 giờ~22 phút
99.99%~52.6 phút~4.3 phút
99.999%~5.26 phút~26 giây

Phần còn lại (100% − SLO) là error budget. SLO 99.9% cho phép ~43 phút lỗi/tháng; còn budget thì được deploy mạnh tay, hết budget thì dừng tính năng mới để tập trung ổn định.

Một điểm hay bị hỏi: các thành phần nối tiếp thì availability nhân với nhau.

Gateway 99.9% → Order 99.9% → DB 99.9%
Tổng ≈ 0.999 × 0.999 × 0.999 ≈ 99.7%

Hai instance song song, mỗi cái 99%:
Tổng ≈ 1 − (0.01 × 0.01) = 99.99%   (nếu lỗi độc lập)

Vì vậy càng nhiều hop đồng bộ thì availability càng giảm; redundancy song song thì kéo nó lên. Chi tiết HA ở 15.6.

5. Back-of-envelope: ước lượng từng bước

Số nhớ nhanh: 1 ngày ≈ 86,400 giây ≈ 105 giây. Peak thường lấy 2–10 lần trung bình.

Bước 1: Giả định (nói to với interviewer)

DAU                    : 10 triệu
Mỗi user xem           : 20 trang sản phẩm/ngày
Order                  : 1 triệu order/ngày
Kích thước 1 order     : ~1 KB (cả order_items)
Response trang sản phẩm: ~20 KB JSON (ảnh đi CDN riêng)
Ảnh                    : 1 triệu sản phẩm × 5 ảnh × 200 KB

Bước 2: QPS

Read : 10M × 20 / 10^5      ≈ 2,000 req/s trung bình
       peak ×5               ≈ 10,000 req/s
Write: 1M / 10^5             ≈ 10 order/s trung bình
       peak (flash sale ×10) ≈ 100 order/s
Read : Write                 ≈ 200 : 1   → read-heavy

Bước 3: Storage

Order : 1M × 1 KB = 1 GB/ngày ≈ 365 GB/năm  (+ index, replica ×3)
Ảnh   : 1M × 5 × 200 KB       = 1 TB        → object storage (S3/Blob)

Bước 4: Bandwidth

Peak : 10,000 req/s × 20 KB = 200 MB/s ≈ 1.6 Gbps (chỉ API)
Ảnh  : nặng hơn nhiều → bắt buộc CDN

Bước 5: Kết luận dẫn đường cho thiết kế

Read-heavy 10k req/s   → cache (Redis), read replica, CDN
100 order/s peak       → 1 PostgreSQL primary vẫn chịu được, chưa cần shard
365 GB/năm             → partition orders theo tháng, archive dữ liệu cũ
Flash sale             → rate limit, hàng đợi, chống oversell

Một ví dụ khác cùng tư duy: URL shortener có 10,000 redirect/s nhưng chỉ ~50 create/s. Thấy ngay READ >>> WRITE → cache là quyết định trung tâm.

6. Cách hoạt động: requirement chảy xuống kiến trúc

Requirement / SLO               Estimate
       │                           │
       └──────────┬────────────────┘
                  ▼
        Bottleneck dự đoán
     (read? write? storage? latency?)
                  ▼
        Quyết định thiết kế
     (cache, replica, shard, async, HA)
                  ▼
        Đo lại bằng SLI trên production

Để tính nhanh trong đầu, có thể viết một hàm nhỏ khi luyện tập:

record Estimate(long dau, int actionsPerUser, int peakFactor, int bytesPerItem) {
    double avgQps()  { return dau * actionsPerUser / 86_400.0; }
    double peakQps() { return avgQps() * peakFactor; }
    double gbPerDay(long itemsPerDay) { return itemsPerDay * bytesPerItem / 1e9; }
}

var reads = new Estimate(10_000_000, 20, 5, 20_000);
System.out.printf("avg=%.0f peak=%.0f%n", reads.avgQps(), reads.peakQps());
// avg=2315 peak=11574

7. So sánh nhanh

SLISLOSLA
Bản chấtSố đoMục tiêuHợp đồng
Ai dùngMonitoringTeam kỹ thuậtBusiness + khách hàng
Vi phạm thì—Hết error budget, dừng featureĐền tiền/credit

8. Khi nào nên / không nên

SLO và SLA nghe giống nhau quá. Vậy chọn SLO 99.9% thì SLA nên để bao nhiêu?

Bạn hiểu gần đúng, chỉ cần chỉnh một điểm: SLO là mục tiêu nội bộ, SLA là lời hứa có hậu quả pháp lý/tiền bạc. Vì vậy SLA phải lỏng hơn SLO:

SLO nội bộ : 99.9%   (~43 phút lỗi/tháng)
SLA với KH : 99.5%   (~3.6 giờ lỗi/tháng)
             └── khoảng đệm để kịp phát hiện và sửa trước khi phải đền

Và SLO nên đặt theo trải nghiệm người dùng, không theo máy: "99.9% checkout thành công" có ý nghĩa hơn "CPU dưới 70%". CPU chỉ là tín hiệu để điều tra.

Nếu mình ước lượng sai, ví dụ lệch 3–4 lần, thì có bị đánh giá thấp không?

Thường là không. Interviewer quan tâm bậc độ lớn (100 hay 10,000 req/s) và việc bạn dùng con số để ra quyết định. Lệch 3 lần không đổi kết luận "read-heavy, cần cache". Lệch 100 lần mới đổi kiến trúc (một DB vs sharding).

Điều bị đánh giá thấp là: tính xong rồi bỏ đó, không dùng con số vào thiết kế. Luôn kết bằng câu "Vì vậy...".

Phỏng vấn hỏi về non-functional requirement, SLO và ước lượng capacity thì trả lời sao?

Q1. Functional và non-functional requirement khác nhau thế nào?

🇻🇳 Tiếng Việt:

Functional mô tả hệ thống làm gì, ví dụ xem sản phẩm, checkout. Non-functional mô tả hệ thống làm tốt tới mức nào: availability, latency, scalability, consistency, security. Non-functional thường quyết định kiến trúc nhiều hơn, nên em luôn cố biến chúng thành con số như SLO.

🇬🇧 English:

Functional requirements describe what the system does, such as viewing products or checking out. Non-functional requirements describe how well it does it: availability, latency, scalability, consistency and security. Non-functional requirements usually drive the architecture more, so I try to turn them into numbers such as SLOs.

Q2. SLI, SLO, SLA là gì?

🇻🇳 Tiếng Việt:

SLI là chỉ số đo được, ví dụ tỉ lệ request thành công hay p99 latency. SLO là mục tiêu nội bộ cho SLI, ví dụ 99.9% trong 30 ngày. SLA là cam kết với khách hàng, vi phạm sẽ có đền bù, nên thường lỏng hơn SLO. Phần còn lại của SLO là error budget, dùng để cân bằng giữa tốc độ release và độ ổn định.

🇬🇧 English:

An SLI is a measured indicator, such as the success rate or p99 latency. An SLO is the internal target for that indicator, for example 99.9% over 30 days. An SLA is a contract with customers with penalties if violated, so it is usually looser than the SLO. The gap below 100% is the error budget, which balances release speed against stability.

Q3. Ước lượng QPS và storage cho một hệ thống thế nào?

🇻🇳 Tiếng Việt:

Em bắt đầu từ DAU và số hành động mỗi user, chia cho khoảng 10 mũ 5 giây mỗi ngày để ra QPS trung bình, rồi nhân hệ số peak. Storage bằng số bản ghi mỗi ngày nhân kích thước, nhân số năm lưu và số replica. Ví dụ 10 triệu DAU, 20 lượt xem mỗi người là khoảng 2 nghìn req/s, peak 10 nghìn; 1 triệu order 1 KB là khoảng 365 GB mỗi năm. Từ đó em kết luận hệ thống read-heavy, cần cache và CDN nhưng chưa cần sharding.

🇬🇧 English:

I start from daily active users and actions per user, divide by roughly 10 to the 5 seconds per day to get average QPS, then apply a peak factor. Storage is records per day times record size, times retention and replication factor. For example, 10 million DAU with 20 views each is about 2,000 requests per second, around 10,000 at peak; 1 million 1 KB orders a day is about 365 GB a year. So the system is read-heavy and needs caching and a CDN, but not sharding yet.

Cách nhớ ngắn gọn


Tự kiểm tra

"Không oversell" là functional hay non-functional?

Thường xếp vào non-functional (correctness/consistency), vì nó nói hệ thống phải đúng tới mức nào, không phải một tính năng mới.

99.9% availability cho phép bao nhiêu downtime mỗi tháng?

Khoảng 43 phút (30 ngày × 24 × 60 × 0.001).

Ba service nối tiếp, mỗi cái 99.9%, tổng là bao nhiêu?

Khoảng 99.7%, vì availability nối tiếp nhân với nhau.

10 triệu DAU, mỗi người 20 request/ngày, peak ×5: peak QPS khoảng bao nhiêu?

10M × 20 / 105 ≈ 2,000 trung bình, peak ≈ 10,000 req/s.

Vì sao SLA thường lỏng hơn SLO?

Để có khoảng đệm: team phát hiện và sửa khi vi phạm SLO nội bộ trước khi chạm tới cam kết có đền bù.