Hệ thống Dữ liệu Phân tán/Scalability — mô tả tải bằng tham số, không bằng cảm tính
3/38
Bài 3 / 38~11 phútTư duy hệ dữ liệu quy mô lớnMiễn phí lượt xem

Scalability — mô tả tải bằng tham số, không bằng cảm tính

Scalability không phải nhãn 'scale được' mà là câu hỏi: khi tham số tải tăng, cần thêm tài nguyên gì để giữ hiệu năng? Load parameter, fan-out, scale-up vs scale-out.

TL;DR: Scalability không phải một tính từ ("hệ này scale được") mà là một câu hỏi định lượng: khi tham số tải tăng, cần thêm tài nguyên gì để giữ hiệu năng? Bước một là mô tả tải bằng tham số (load parameter) — request/giây, tỉ lệ đọc/ghi, số kết nối đồng thời, fan-out — chứ không nói "nhiều người dùng". Bước hai là chọn hướng mở rộng: scale-up (máy mạnh hơn) hay scale-out (nhiều máy hơn). Scale-up đơn giản nhưng đụng trần vật lý và giá; scale-out gần như vô hạn nhưng kéo theo mọi bài toán phân tán của track này. Đo hiệu năng bằng response time phân phối (percentile), không bằng trung bình — lý do sẽ rõ ở bài tail latency.

Khi ai đó nói "hệ của tôi scale được", hãy hỏi lại: scale theo tham số nào? Một hệ mở rộng tốt khi số người đọc tăng có thể sập khi số người ghi tăng — hai tham số tải khác nhau, hai bài toán khác nhau. Không có "scalable" chung chung; chỉ có "scalable theo tham số X".

Bài này cho bạn cách nói về tải một cách cụ thể để câu hỏi mở rộng trở nên trả lời được, rồi so hai hướng mở rộng cơ bản.

Nhớ lại Load balancer L4/L7

Scale-out cần một lớp chia tải trước nhiều máy. Bạn đã học load balancer phân phối request qua nhiều backend (round-robin, least-connections, L4 vs L7). Bài này giả định cơ chế đó — ở đây tập trung khi nào cần nhiều máy, không chia thế nào.

1. Analogy — quán ăn giờ cao điểm

Một quán ăn phục vụ tốt lúc vắng. Câu hỏi scalability là: khi khách tăng gấp đôi, làm sao giữ thời gian ra món như cũ? Có hai cách. Thuê một siêu đầu bếp làm nhanh gấp đôi (scale-up) — nhưng không có đầu bếp nào nhanh vô hạn, và người giỏi nhất đắt phi lý. Hoặc mở thêm nhiều bếp song song (scale-out) — gần như thêm bao nhiêu cũng được, nhưng giờ phải điều phối: chia đơn cho bếp nào, gộp món ra sao, bếp này nghỉ thì đơn đi đâu.

Quán ănHệ dữ liệu
Số khách/giờ, tỉ lệ món khó/dễLoad parameter (request/s, đọc/ghi)
Thời gian ra mónResponse time
Thuê siêu đầu bếpScale-up (máy mạnh hơn)
Mở nhiều bếp song songScale-out (nhiều máy hơn)
Điều phối đơn giữa các bếpLoad balancing + phân tán
💡 Cách nhớ

Scale-up = một bếp mạnh hơn (đụng trần). Scale-out = nhiều bếp hơn (vô hạn nhưng phải điều phối). Cả track này là nghệ thuật điều phối nhiều bếp.

2. Mô tả tải bằng tham số — "nhiều" là vô nghĩa

Câu "hệ chịu được nhiều tải không" không trả lời được cho tới khi định nghĩa tải bằng con số. Load parameter là đại lượng mô tả tải phù hợp với hệ:

  • Throughput — số request (hoặc bản ghi) xử lý mỗi giây.
  • Tỉ lệ đọc/ghi — một hệ đọc-nhiều và một hệ ghi-nhiều mở rộng theo hai hướng hoàn toàn khác.
  • Số kết nối đồng thời — bao nhiêu client giữ kết nối cùng lúc.
  • Fan-out — một thao tác kéo theo bao nhiêu thao tác phụ. Ví dụ: một người đăng bài, hệ phải ghi vào feed của hàng nghìn người theo dõi — một ghi logic nở thành hàng nghìn ghi thật.
Thử đoán trước

Một mạng xã hội "chịu được" 10.000 bài đăng/giây, nhưng mỗi bài phải ghi vào feed của trung bình 500 người theo dõi. Đoán trước khi đọc tiếp: tải ghi thật mỗi giây là bao nhiêu — vẫn cỡ 10.000, hay lớn hơn nhiều? Nhân thử hai con số trước khi xem đáp án.

Chọn đúng load parameter là nửa lời giải. Fan-out là ví dụ kinh điển: hệ "chịu được" 10.000 bài đăng/giây nghe ổn, nhưng nếu mỗi bài fan-out tới trung bình 500 người theo dõi thì tải ghi thật là 5 triệu/giây — con số hoàn toàn khác. Nói "10.000 bài/giây" mà quên fan-out là mô tả tải sai.

3. Đo hiệu năng — nhìn phân phối, không nhìn trung bình

Khi tải tăng, "hiệu năng" (response time) phải đo bằng phân phối (percentile p50/p95/p99), không phải trung bình — trung bình giấu mất những request chậm nhất. Đây là câu hỏi được đào sâu trọn vẹn ở bài 03 — Tail latency: vì sao trung bình nói dối, và tail bị khuếch đại ra sao khi fan-out.

4. Scale-up hay scale-out — chọn hướng mở rộng nào?

Scale-up (vertical) — thay bằng máy mạnh hơn: nhiều CPU, nhiều RAM. Ưu: đơn giản, không đổi kiến trúc, code chạy y nguyên. Nhược: có trần vật lý (không có máy vô hạn mạnh) và giá tăng phi tuyến — máy gấp đôi sức mạnh thường đắt hơn gấp đôi rất nhiều.

Scale-out (horizontal) — thêm nhiều máy thường, chia việc ra: đặt một lớp chia tải (load balancer) trước nhiều bản. Ưu: mở rộng gần như vô hạn bằng phần cứng rẻ, và nhiều máy còn giúp reliability (redundancy — nhớ bài 01). Nhược: kéo theo mọi bài toán phân tán — dữ liệu phải nhân bản hoặc phân mảnh, các máy phải đồng bộ, và xuất hiện các fault mà một máy không có (một node chết giữa chừng, mạng giữa các máy không tin cậy).

flowchart TB
  subgraph UP["Scale-up (vertical)"]
    S1["1 may nho"] --> S2["1 may lon hon (nhieu CPU/RAM)"]
  end
  subgraph OUT["Scale-out (horizontal)"]
    LB["Load balancer"] --> N1["may 1"]
    LB --> N2["may 2"]
    LB --> N3["may 3"]
  end

Thực tế phần lớn hệ lớn dùng cả hai: scale-up tới điểm giá còn hợp lý, rồi scale-out. Nhưng scale-out là lý do cả track này tồn tại — nó đổi bài toán "làm máy mạnh hơn" (kỹ thuật phần cứng) thành "phối hợp nhiều máy không tin cậy" (kỹ thuật phân tán).

5. Pitfall — "cứ mua máy to hơn" và đo bằng trung bình

Pitfall — scale-up như phản xạ, và giấu tail sau trung bình

Hai sai lầm hay đi cùng nhau:

❌ "He cham? Mua may to gap doi."
   -> dung 1 thoi gian, roi lai dung tran vat ly + gia phi tuyen
   -> van la MOT may -> single point of failure (nho bai 01)

❌ Do bang response time TRUNG BINH -> thay dep -> tuong on
   -> tail (p99) van cao -> 1% nguoi dung kho so ma dashboard khong thay

Scale-up như phản xạ đầu tiên trì hoãn bài toán thật và tích nợ: tới lúc buộc phải scale-out, hệ đã lớn và khó tách. Còn đo bằng trung bình khiến đội tin hệ "đủ nhanh" trong khi đuôi phân phối đang hỏng.

Hướng đúng: mô tả tải bằng đúng load parameter (gồm fan-out), đo response time bằng percentile (p95/p99), và cân nhắc scale-out trước khi đụng trần scale-up — kiến trúc chịu phân tán dễ dựng khi hệ còn nhỏ hơn là khi đã khổng lồ. Chọn scale-up hay scale-out là quyết định theo tham số tải + ngân sách, không theo thói quen.

6. 📚 Đào sâu — nguồn gốc & tài liệu

📚 Đào sâu — Scalability
  • Designing Data-Intensive Applications (Kleppmann) — Chương 1, mục "Scalability" — load parameter, mô tả tải bằng tham số, đo bằng percentile response time, và cách nghĩ "khi tải tăng, thêm tài nguyên thế nào".
  • Khái niệm fan-out như một load parameter được DDIA minh hoạ qua bài toán feed mạng xã hội (write fan-out vs read fan-in) — một ví dụ chuẩn cho việc chọn đúng tham số tải.

Ghi chú: DDIA Ch1 nhấn mạnh scalability là câu hỏi có điều kiện ("scale theo tham số nào"), không phải nhãn nhị phân — nền tư duy cho toàn bộ phần replication/partitioning sau này.

7. Liên hệ các bài khác

  • Bài 01 — Reliability: scale-out thêm máy vừa tăng throughput vừa tạo redundancy (reliability) — nhưng cũng thêm fault phân tán; hai thước đo đan vào nhau.
  • Bài 03 — Tail latency: mục 3 chỉ bắc cầu tới percentile — bài 03 đào sâu vì sao p99 mới là thước đo trải nghiệm thật, và tail bị khuếch đại khi fan-out.
  • Bài 04 — Maintainability: scale-out làm hệ phức tạp hơn để vận hành — đánh đổi với simplicity, một trục của maintainability.

8. Tóm tắt

  • Scalability là câu hỏi định lượng theo từng load parameter, không phải nhãn "scale được".
  • Mô tả tải bằng tham số: throughput, tỉ lệ đọc/ghi, kết nối đồng thời, fan-out — chọn đúng tham số là nửa lời giải.
  • Đo hiệu năng bằng phân phối response time (percentile), không bằng trung bình — trung bình giấu tail.
  • Scale-up: đơn giản nhưng đụng trần vật lý + giá phi tuyến. Scale-out: gần vô hạn + tăng redundancy, nhưng kéo theo mọi bài toán phân tán.
  • Hệ lớn thường dùng cả hai; scale-out là lý do track này tồn tại — đổi "máy mạnh hơn" thành "phối hợp nhiều máy không tin cậy".
  • Anti-pattern: scale-up như phản xạ + đo bằng trung bình → trì hoãn bài toán thật và giấu tail hỏng.

9. Tự kiểm tra

Tự kiểm tra
Q1
Vì sao nói 'hệ này scalable' là một phát biểu chưa đủ nghĩa? Phải bổ sung gì để nó trở nên trả lời được?

Vì scalability luôn gắn với một tham số tải cụ thể. Một hệ mở rộng tốt khi số người đọc tăng có thể sập khi số người ghi tăng — hai load parameter khác nhau, hai bài toán khác nhau. "Scalable" chung chung che giấu chuyện đó.

Phải bổ sung: scale theo tham số nào (throughput đọc? ghi? fan-out? kết nối đồng thời?) và giữ hiệu năng nào (p99 dưới bao nhiêu ms). Khi đó câu hỏi thành: "khi tham số X tăng gấp đôi, cần thêm tài nguyên gì để giữ p99" — trả lời được.

Q2
Một hệ xử lý 10.000 bài đăng/giây, mỗi bài fan-out tới trung bình 500 người theo dõi. Vì sao mô tả tải chỉ bằng '10.000 bài/giây' là sai, và tải ghi thật là bao nhiêu?

Fan-out là một load parameter bị bỏ quên: một ghi logic (đăng bài) nở thành nhiều ghi thật (ghi vào feed từng người theo dõi). Mô tả tải bằng "10.000 bài/giây" chỉ đếm ghi logic, không đếm ghi thật mà hệ phải làm.

Tải ghi thật ≈ 10.000 × 500 = 5 triệu ghi/giây — lớn gấp 500 lần con số "10.000", hơn hai bậc độ lớn. Chọn sai load parameter dẫn tới đánh giá sai hoàn toàn khả năng mở rộng; đây là lý do phải chọn tham số phản ánh đúng công việc hệ làm.

Q3
Một hệ đang scale-up (mua máy mạnh hơn) đã đụng trần giá phi tuyến, trong khi tải ghi vẫn tăng đều. Bạn đề xuất hướng scale nào, và cần chuẩn bị đánh đổi gì?

Đề xuất scale-out: chuyển sang nhiều máy thường thay vì tiếp tục đẩy một máy lên cấu hình cao hơn — scale-up đã hết dư địa hợp lý về giá, và dù có đẩy tiếp thì hệ vẫn là một máy (single point of failure).

Đánh đổi cần chuẩn bị: scale-out kéo theo toàn bộ bài toán phân tán — dữ liệu phải nhân bản hoặc phân mảnh, các máy phải đồng bộ, và xuất hiện fault mới (một node chết giữa chừng, mạng giữa các máy không tin cậy) mà kiến trúc một máy không gặp phải. Nên cân nhắc bước này trước khi kịch trần scale-up, vì kiến trúc chịu phân tán dễ dựng khi hệ còn nhỏ hơn.

Q4
So sánh scale-up và scale-out về ưu/nhược. Vì sao scale-out là lý do cả track phân tán này tồn tại?
  • Scale-up (máy mạnh hơn): đơn giản, không đổi kiến trúc; nhưng đụng trần vật lý và giá tăng phi tuyến, và vẫn là một máy (single point of failure).
  • Scale-out (nhiều máy): mở rộng gần vô hạn bằng phần cứng rẻ, thêm redundancy; nhưng kéo theo mọi bài toán phân tán — nhân bản/phân mảnh dữ liệu, đồng bộ, và fault mới (node chết, mạng không tin cậy).

Scale-out đổi bản chất bài toán: từ "làm máy mạnh hơn" (kỹ thuật phần cứng) thành "phối hợp nhiều máy không tin cậy" (kỹ thuật phân tán) — chính là chủ đề của replication, partitioning, consensus ở các module sau.

Q5
Vì sao 'cứ mua máy to hơn' khi hệ chậm là một phản xạ tích nợ, dù nó giải quyết được vấn đề trước mắt?

Vì scale-up chỉ mua thời gian: rồi sẽ đụng trần vật lý và giá phi tuyến, và suốt thời gian đó hệ vẫn là một máy — một single point of failure (bài 01). Bài toán thật (phối hợp nhiều máy) bị trì hoãn, không biến mất.

Nợ nằm ở chỗ: kiến trúc chịu phân tán dễ dựng khi hệ còn nhỏ hơn là khi đã khổng lồ và rối. Càng trì hoãn scale-out, lúc buộc phải làm càng đắt và rủi ro. Nên cân nhắc scale-out trước khi kịch trần scale-up, thay vì coi mua máy to là lời giải cuối.

Bài tiếp theo: Tail latency — đo bằng p99, không bằng trung bình

Bài này có giúp bạn hiểu bản chất không?

Hỏi đáp về bài này

Chưa có câu hỏi

Đặt câu hỏi

Có gì chưa rõ trong bài? Đặt câu hỏi đầu tiên — câu trả lời từ cộng đồng giúp bạn (và người sau).

Đặt câu hỏi đầu tiên