Mở đầu — vì sao bài này quan trọng
Hãy tưởng tượng bạn đang vận hành hệ thống bán vé concert cho một sự kiện lớn ở Việt Nam. Bình thường website chạy êm ru với vài nghìn người dùng mỗi ngày. Nhưng đúng 12 giờ trưa ngày mở bán, hàng trăm nghìn người cùng lúc bấm nút "Đặt vé". Nếu bạn không chuẩn bị đủ CPU, RAM, kết nối database và băng thông, hệ thống sẽ sập trong vài giây — và bạn sẽ trở thành đề tài chế ảnh trên mạng xã hội suốt cả tuần.
Đó chính là lý do Capacity Planning (lập kế hoạch năng lực) tồn tại. Nó là kỹ năng trả lời một câu hỏi tưởng đơn giản nhưng cực kỳ khó: "Chúng ta cần bao nhiêu tài nguyên để phục vụ lượng traffic dự kiến, cộng thêm dư địa cho những đợt tăng đột biến, mà không phải trả tiền lãng phí cho những resource không dùng đến?"
Capacity Planning nằm ở giao điểm giữa ba mối lo của một kỹ sư vận hành: độ tin cậy (hệ thống không được sập khi tải tăng), chi phí (không được đốt tiền cho tài nguyên nhàn rỗi), và tốc độ (phải chuẩn bị đủ sớm để kịp mua/cấp phát hạ tầng). Làm tốt bài này, bạn ngủ ngon vào những đêm cao điểm. Làm ẩu, bạn thức trắng và mất khách hàng.
Trong bài này, chúng ta tập trung riêng vào hai trụ cột: Forecast (dự báo nhu cầu) và Headroom (dư địa an toàn). Đây là phần cốt lõi và mang tính nền tảng nhất của Capacity Planning. Những chủ đề liên quan như load testing hay auto-scaling sẽ được đào sâu ở các bài sau — ở đây chúng ta xây móng trước.
Khái niệm cốt lõi
Capacity Planning là gì và không phải là gì
Capacity Planning là quá trình dự báo nhu cầu tài nguyên trong tương lai dựa trên dữ liệu quá khứ, kế hoạch kinh doanh và các sự kiện đặc biệt, rồi từ đó quyết định cần cấp phát bao nhiêu tài nguyên. Tài nguyên ở đây không chỉ là CPU. Nó bao gồm nhiều "chiều" (dimension) khác nhau:
- CPU: khả năng xử lý tính toán.
- RAM (Memory): bộ nhớ để giữ dữ liệu đang xử lý và cache.
- Database connections: số kết nối đồng thời tới cơ sở dữ liệu — thường là điểm nghẽn (bottleneck) bị bỏ quên nhất.
- Bandwidth / Network I/O: băng thông truyền tải dữ liệu.
- Disk I/O và Storage: tốc độ đọc ghi và dung lượng lưu trữ.
Cần phân biệt rõ: Capacity Planning không phải là auto-scaling. Auto-scaling là cơ chế phản ứng tức thời với tải hiện tại (bài sau sẽ nói kỹ). Capacity Planning mang tính chủ động và có tầm nhìn xa — nó trả lời câu hỏi "quý sau chúng ta cần bao nhiêu", "sự kiện Black Friday tháng tới cần chuẩn bị gì", chứ không chỉ "ngay bây giờ cần thêm mấy con server".
Ba input chính của một forecast
Một bản dự báo năng lực đáng tin cậy được xây dựng từ ba nguồn dữ liệu đầu vào:
1. Historical baseline (đường cơ sở lịch sử). Đây là nền tảng của mọi dự báo. Bạn nhìn vào dữ liệu quá khứ để hiểu hành vi bình thường của hệ thống: một request tiêu tốn bao nhiêu CPU-millisecond, mỗi 1.000 người dùng đồng thời cần bao nhiêu RAM, tỷ lệ request/giây (RPS) ở giờ cao điểm là bao nhiêu. Baseline cho bạn biết "chi phí tài nguyên trên mỗi đơn vị traffic". Không có baseline, bạn chỉ đang đoán mò.
2. Growth forecast (dự báo tăng trưởng). Business không đứng yên. Marketing dự định chạy chiến dịch lớn, sản phẩm sắp ra tính năng mới thu hút người dùng, công ty đặt mục tiêu tăng trưởng 15% mỗi quý. Bạn phải chuyển những con số kinh doanh này thành con số tài nguyên. Tăng trưởng có thể là tuyến tính (linear — đều đặn theo thời gian) hoặc theo cấp số nhân (exponential — điển hình cho startup đang bùng nổ). Nhận diện sai mô hình tăng trưởng là một sai lầm đắt giá.
3. Seasonal & event spikes (biến động mùa vụ và sự kiện). Traffic hiếm khi phẳng. Có chu kỳ ngày (giờ trưa và tối cao hơn giờ khuya), chu kỳ tuần (cuối tuần khác ngày thường), chu kỳ mùa (Tết, 11/11, 12/12, Black Friday). Và có những sự kiện một lần: ra mắt sản phẩm, chương trình flash sale, viral trên mạng xã hội. Những đỉnh này (peak) mới là thứ đánh sập hệ thống, chứ không phải mức trung bình.
Headroom — tại sao không bao giờ chạy ở 100%
Headroom là phần dư địa tài nguyên bạn cố tình để trống, không dùng đến trong điều kiện bình thường. Nếu tải trung bình dùng hết 60% CPU thì bạn còn 40% headroom.
Nhiều người mới vào nghề thắc mắc: "Tại sao không tận dụng hết 100% cho tiết kiệm?" Câu trả lời là headroom tồn tại để hấp thụ ba loại bất định:
- Spike đột ngột: một đợt traffic tăng vọt trước khi auto-scaling kịp phản ứng (thường mất vài phút để khởi động instance mới).
- Sự cố mất node: nếu bạn chạy 5 server ở mức 80% mà một con chết, tải của nó dồn sang 4 con còn lại, đẩy chúng lên 100% và gây sập dây chuyền (cascading failure).
- Sai số dự báo: dự báo luôn có sai lệch. Headroom là biên an toàn cho phần bạn đoán sai.
Có một khái niệm gắn liền với headroom là N+1 redundancy: bạn luôn cấp phát nhiều hơn nhu cầu tối thiểu ít nhất một đơn vị, để khi mất một node hệ thống vẫn chịu tải được. Với hệ thống trọng yếu, người ta còn dùng N+2.
Tình huống thực tế
Ví dụ 1 — Sàn TMĐT chuẩn bị cho ngày 11/11
Một sàn thương mại điện tử tại Việt Nam (gọi là ShopViet) chuẩn bị cho sự kiện sale 11/11. Đội SRE nhìn vào historical baseline: ngày thường hệ thống xử lý khoảng 3.000 RPS ở giờ cao điểm tối, với cụm 20 server API chạy trung bình 55% CPU.
Nhìn vào dữ liệu 11/11 năm ngoái, họ thấy đỉnh traffic đạt 8 lần ngày thường trong khung 15 phút đầu sau nửa đêm — tức khoảng 24.000 RPS. Marketing năm nay dự báo tăng trưởng người dùng 40% so với năm ngoái, nên họ ước tính đỉnh có thể chạm ~34.000 RPS.
Bài toán: nếu 20 server xử lý 3.000 RPS ở 55%, thì công suất tối đa lý thuyết mỗi server là khoảng 273 RPS (3.000 / 20 / 0.55). Để phục vụ 34.000 RPS ở mức headroom an toàn 60%, họ cần: 34.000 / (273 × 0.60) ≈ 208 server. Họ làm tròn lên 220 server để có thêm N+2 redundancy và biên cho sai số dự báo.
Bài học rút ra: đừng bao giờ lập kế hoạch dựa trên traffic trung bình. ShopViet lên kế hoạch cho đỉnh của đỉnh — peak nhân với hệ số tăng trưởng — rồi mới cộng headroom. Họ cũng cấp phát trước (pre-provision) từ tối hôm trước thay vì trông chờ auto-scaling, vì spike 11/11 đến quá nhanh, không hạ tầng tự động nào kịp bung ra 200 server trong 15 phút.
Ví dụ 2 — Startup fintech và cái bẫy database connection
Một startup fintech ở Đông Nam Á (gọi là PayFlow) tăng trưởng nóng, lượng giao dịch tăng gấp đôi mỗi hai tháng. Đội kỹ thuật rất chú tâm scale tầng ứng dụng: mỗi khi CPU tăng, auto-scaling thêm pod, mọi thứ có vẻ ổn.
Rồi một đêm, hệ thống sập dù CPU của các service chỉ ở mức 45%. Điều tra ra: PostgreSQL của họ cấu hình tối đa 200 connection. Khi số pod ứng dụng tăng lên, mỗi pod mở một connection pool riêng, tổng số connection vượt 200. Database từ chối kết nối mới, và toàn bộ hệ thống tê liệt trong khi CPU vẫn "xanh".
Đây là minh họa kinh điển cho nguyên tắc "chiều yếu nhất". PayFlow đã forecast rất tốt cho CPU nhưng quên hoàn toàn chiều database connection. Họ đã scale một chiều mà bỏ mặc chiều còn lại.
Bài học rút ra: Capacity Planning phải bao phủ mọi chiều tài nguyên, đặc biệt là các tài nguyên khó co giãn như database connection, disk IOPS, hay giới hạn của các dịch vụ bên thứ ba. PayFlow sau đó thêm một connection pooler (PgBouncer) ở giữa, và đưa "số connection tối đa của DB" vào bảng theo dõi capacity như một chỉ số hạng nhất (first-class metric).
Ví dụ 3 — Nền tảng học trực tuyến và mùa thi
Một nền tảng học trực tuyến (gọi là EduPlus) có traffic khá phẳng quanh năm, nhưng tăng vọt vào hai giai đoạn: đầu năm học và mùa ôn thi cuối kỳ. Trong mùa thi, lượng người xem video bài giảng đồng thời tăng gấp 5 lần, kéo theo băng thông (bandwidth) tăng dữ dội chứ không phải CPU.
Ban đầu EduPlus chỉ theo dõi CPU và RAM, nên họ hoàn toàn bất ngờ khi hóa đơn CDN và bandwidth tăng đột biến, đồng thời một số vùng bị nghẽn mạng khiến video giật lag. Họ đã forecast sai chiều tài nguyên chủ đạo: với dịch vụ streaming, băng thông mới là nút cổ chai, không phải compute.
Bài học rút ra: mỗi loại workload có "chiều thống trị" khác nhau. Ứng dụng tính toán nặng thì CPU-bound; ứng dụng caching thì memory-bound; streaming thì bandwidth-bound; hệ thống ghi log nhiều thì disk-I/O-bound. Trước khi forecast, hãy xác định hệ thống của bạn bị giới hạn bởi chiều nào, rồi tập trung dự báo và để headroom cho chiều đó.
Hướng dẫn từng bước
Đây là quy trình bảy bước để làm một bản Capacity Plan cho hệ thống của bạn:
Bước 1 — Xác định chiều tài nguyên chủ đạo. Trả lời câu hỏi: hệ thống của tôi bị giới hạn bởi cái gì trước tiên? CPU, RAM, connection, bandwidth hay disk? Chạy quan sát trong vài tuần để biết chiều nào chạm ngưỡng sớm nhất khi tải tăng.
Bước 2 — Thiết lập baseline. Thu thập số liệu: một đơn vị traffic (ví dụ 1.000 người dùng đồng thời hoặc 1.000 RPS) tiêu tốn bao nhiêu tài nguyên trên mỗi chiều. Đây gọi là unit cost (chi phí đơn vị). Ví dụ: "1.000 RPS ≈ 4 CPU core + 30 database connection".
Bước 3 — Lấy growth forecast từ business. Ngồi với đội sản phẩm và kinh doanh. Hỏi họ mục tiêu tăng trưởng người dùng theo quý, kế hoạch chiến dịch marketing, ngày ra mắt tính năng lớn. Chuyển các con số kinh doanh này thành con số traffic dự kiến.
Bước 4 — Nhận diện các đỉnh mùa vụ và sự kiện. Liệt kê các mốc sẽ gây spike: Tết, 11/11, 12/12, kỳ nghỉ lễ, các sự kiện đặc thù của ngành bạn. Với mỗi mốc, ước tính hệ số nhân so với ngày thường dựa trên lịch sử.
Bước 5 — Tính nhu cầu đỉnh. Công thức tổng quát:
Nhu cầu đỉnh = Baseline × Hệ số tăng trưởng × Hệ số spike đỉnh
Số resource cần = Nhu cầu đỉnh / (Công suất mỗi đơn vị × Mức headroom)
Luôn tính cho kịch bản đỉnh, không phải trung bình.
Bước 6 — Cộng headroom và redundancy. Áp mức sử dụng mục tiêu 50–70%, và cộng thêm N+1 hoặc N+2 redundancy để chịu được mất node. Với tài nguyên khó co giãn, để headroom rộng hơn.
Bước 7 — Theo dõi và hiệu chỉnh liên tục. Capacity Plan không phải làm một lần rồi quên. Đặt dashboard theo dõi mức sử dụng thực tế so với dự báo, và đặt cảnh báo (alert) khi mức sử dụng vượt ngưỡng headroom. Sau mỗi sự kiện lớn, so sánh dự báo với thực tế để hiệu chỉnh mô hình cho lần sau.
Lỗi thường gặp & mẹo
Lỗi 1 — Lập kế hoạch theo mức trung bình thay vì đỉnh. Đây là sai lầm phổ biến nhất. Traffic trung bình có thể chỉ là 3.000 RPS nhưng đỉnh 15 phút là 24.000 RPS. Hệ thống sập ở đỉnh, không phải ở trung bình. Mẹo: luôn dùng phân vị cao (p95, p99) hoặc đỉnh thực tế làm cơ sở, không dùng mean.
Lỗi 2 — Chỉ nhìn một chiều tài nguyên. Như trường hợp PayFlow, dồn hết chú ý vào CPU mà quên database connection. Mẹo: lập một bảng liệt kê tất cả các chiều, và với mỗi chiều ghi rõ ngưỡng tối đa và mức sử dụng hiện tại.
Lỗi 3 — Nhầm mô hình tăng trưởng. Áp mô hình tuyến tính cho một sản phẩm đang tăng theo cấp số nhân sẽ khiến bạn thiếu hụt nghiêm trọng chỉ sau vài tháng. Mẹo: vẽ biểu đồ dữ liệu lịch sử ra và nhìn hình dạng đường cong trước khi chọn mô hình.
Lỗi 4 — Tin tưởng mù quáng vào auto-scaling. Auto-scaling cần thời gian khởi động (thường vài phút) và có giới hạn quota. Nó không cứu được spike tức thời hay khi bạn đã chạm trần tài khoản cloud. Mẹo: với sự kiện đã biết trước như 11/11, hãy pre-provision — cấp phát tài nguyên trước, không trông cậy hoàn toàn vào tự động.
Lỗi 5 — Để headroom quá thấp để tiết kiệm. Chạy ở 90% CPU nghe có vẻ tiết kiệm, nhưng chỉ một node chết là sập dây chuyền. Mẹo: tính chi phí một lần downtime (mất khách, mất doanh thu, mất uy tín) và so với chi phí headroom — thường headroom rẻ hơn nhiều.
Lỗi 6 — Không kiểm chứng dự báo. Làm plan xong bỏ vào ngăn kéo, không bao giờ so sánh với thực tế. Mẹo: sau mỗi kỳ, đối chiếu dự báo với số thực và ghi lại sai số để lần sau chính xác hơn.
Bài tập thực hành
Hãy áp dụng ngay với một hệ thống giả định. Bạn vận hành một ứng dụng giao đồ ăn với dữ liệu sau:
- Baseline: giờ cao điểm trưa hiện tại là 5.000 RPS, chạy trên 25 server API ở mức 60% CPU.
- Growth forecast: business dự báo tăng 30% người dùng trong 6 tháng tới.
- Spike: ngày có mưa lớn, đơn hàng tăng gấp 2,5 lần so với ngày thường.
- Tính công suất tối đa (RPS) của một server ở mức 100% CPU.
- Tính nhu cầu đỉnh (RPS) cho kịch bản: sau 6 tháng, gặp ngày mưa lớn.
- Tính số server cần thiết để phục vụ nhu cầu đỉnh đó ở mức headroom an toàn (giữ CPU tối đa 65%).
- Cộng thêm N+2 redundancy và đưa ra con số cuối cùng.
- Liệt kê thêm ít nhất hai chiều tài nguyên khác ngoài CPU mà bạn cần kiểm tra cho hệ thống này, và giải thích vì sao.
Tóm tắt
Capacity Planning là kỹ năng đảm bảo hệ thống luôn có đủ tài nguyên — CPU, RAM, database connection, bandwidth — để phục vụ traffic dự kiến cộng với dư địa cho những đợt tăng đột biến, mà không lãng phí chi phí.
Ba điều cốt lõi cần nhớ:
- Ba input của forecast: historical baseline (nền tảng dữ liệu quá khứ), growth forecast (tăng trưởng từ business), và seasonal/event spikes (các đỉnh mùa vụ và sự kiện). Luôn lập kế hoạch cho đỉnh của đỉnh, không phải mức trung bình.
- Headroom là bảo hiểm, không phải lãng phí. Giữ mức sử dụng 50–70% để hấp thụ spike đột ngột, mất node và sai số dự báo. Kèm theo N+1/N+2 redundancy cho các thành phần trọng yếu.
- Hệ thống chỉ mạnh bằng chiều tài nguyên yếu nhất. Đừng chỉ nhìn CPU; xác định chiều thống trị của workload và forecast cho đủ mọi chiều.