Skip to content

Phương pháp luận Thiết kế Hệ thống

Lời mở đầu

Thiết kế hệ thống không phải là vẽ sơ đồ kiến trúc theo cảm tính, mà là một phương pháp luận có quy tắc rõ ràng. Cho dù là bài toán thiết kế hệ thống trong phỏng vấn hay thiết kế kiến trúc trong công việc thực tế, đều tuân theo khung tư duy tương tự: trước hết nắm rõ vấn đề, sau đó ước tính quy mô, tiếp đó thiết kế phương án, cuối cùng đi sâu tối ưu.

Bài viết này sẽ giúp bạn học được gì?

Sau khi học xong chương này, bạn sẽ đạt được:

  • Quy trình thiết kế: Nắm vững khung phương pháp bốn bước của thiết kế hệ thống
  • Ước tính dung lượng: Học kỹ năng "ước tính mặt sau phong bì"
  • Mẫu phổ biến: Quen thuộc với các mẫu cốt lõi như cache, phân DB/phân bảng, message queue
  • Tư duy đánh đổi: Hiểu tư duy trade-off trong thiết kế kiến trúc
  • Kịch bản thực chiến: Hiểu quá trình thiết kế thông qua các kịch bản như dịch vụ short link, feed stream
ChươngNội dungKhái niệm cốt lõi
Chương 1Phương pháp bốn bướcLàm rõ nhu cầu, ước tính dung lượng, thiết kế kiến trúc, đi sâu tối ưu
Chương 2Ước tính dung lượngQPS, lưu trữ, băng thông, ước tính mặt sau phong bì
Chương 3Mẫu thiết kế cốt lõiCache, phân DB/phân bảng, message queue, CDN
Chương 4Tư duy đánh đổiNhất quán vs Khả dụng, Hiệu suất vs Chi phí
Chương 5Kịch bản kinh điểnDịch vụ short link, Feed stream, Hệ thống flash sale

1. Phương pháp bốn bước thiết kế hệ thống

Thiết kế hệ thống không phải là vẽ sơ đồ kiến trúc ngay từ đầu. Cho dù trong phỏng vấn hay thực chiến, đều nên tuân theo một quy trình có cấu trúc.

Four-Step System Design Method
Click each step to inspect the details
1
Clarify requirements
~5 min
2
Estimate capacity
~5 min
3
Design architecture
~15 min
4
Deep dive
~10 min
Clarify requirements
Do not rush into drawing architecture diagrams. First clarify the problem, scale, core features, and non-functional requirements.
What are the core features? (MVP scope)
Expected user scale? DAU / QPS
Read/write ratio?
Data volume? How much data must be stored?
Availability target? How many nines?
Latency target? What P99 latency is acceptable?
Example: designing a URL shortener
URL shortener: create short links (write) and redirect (read), roughly 100:1 read/write ratio, 100 million redirects per day, links never expire.

Tại sao phải làm rõ nhu cầu trước?

Nhiều người nhận đề bài đã bắt đầu vẽ sơ đồ, kết quả thiết kế một hệ thống "đúng nhưng không phải điều người phỏng vấn muốn". Dành 5 phút hỏi rõ nhu cầu có thể tránh được 30 phút làm lại sau đó.

Các câu hỏi làm rõ phổ biến:

  • Chức năng cốt lõi của hệ thống là gì? (Không cần thiết kế tất cả chức năng)
  • Quy mô người dùng lớn bao nhiêu? (Quyết định có cần phân tán hay không)
  • Tỷ lệ đọc/ghi? (Quyết định chiến lược cache)
  • Dữ liệu cần lưu bao lâu? (Quyết định phương án lưu trữ)

2. Ước tính dung lượng: Nghệ thuật mặt sau phong bì

"Back-of-envelope estimation" (Ước tính mặt sau phong bì) là kỹ năng cốt lõi trong thiết kế hệ thống. Không cần tính toán chính xác, chỉ cần biết bậc lượng.

Back-of-the-Envelope Estimator
Enter basic numbers to estimate system capacity requirements
Daily requests
2000.0 ten thousand
Average QPS
231
Peak QPS
693
Daily bandwidth
102.4 GB
Peak bandwidth
3.5 MB/s
Common estimation references
1 day86,400 seconds
1 month~2.5M seconds
QPS 1000~1 eight-core server
100M/day~1,200 QPS
Single MySQL node~5,000 QPS
Single Redis node~100,000 QPS

Bảng tra đổi nhanh thường dùng

Bậc lượngQuy đổiMẹo ghi nhớ
1 ngày86.400 giây≈ 100.000 giây
100 triệu yêu cầu/ngày≈ 1.200 QPSChia cho 100.000
1 KB x 100 triệu≈ 100 GB100 triệu bản ghi nhỏ
1 MB x 1 triệu≈ 1 TB1 triệu hình ảnh

Áp dụng quy tắc 80/20 trong ước tính

Hầu hết hệ thống tuân theo quy tắc 80/20: 20% dữ liệu gánh 80% yêu cầu. Điều này có nghĩa:

  • Kích thước cache ≈ Tổng dung lượng dữ liệu x 20%
  • QPS điểm nóng ≈ Tổng QPS x 80% tập trung vào 20% key
  • Tỷ lệ trúng cache mục tiêu ≈ 80%+ (thấp hơn mức này thì chiến lược cache có vấn đề)

3. Mẫu thiết kế cốt lõi

Các mẫu xuất hiện lặp đi lặp lại trong thiết kế hệ thống, nắm vững chúng có thể đối phó với hầu hết các kịch bản.

3.1 Mẫu Cache

MẫuĐường đọcĐường ghiPhù hợp
Cache-AsideTrước query cache, miss thì query DB và điền lạiTrước ghi DB, sau đó xóa cacheKịch bản thông thường, phổ biến nhất
Read-ThroughTầng cache tự động load từ DBGiống Cache-AsideCần framework cache hỗ trợ
Write-BehindGiống Cache-AsideTrước ghi cache, bất đồng bộ ghi DBGhi nhiều, có thể chấp nhận mất dữ liệu

Tại sao là "xóa cache" chứ không phải "cập nhật cache"?

Cập nhật cache trong kịch bản đồng thời dễ gây dữ liệu không nhất quán: thread A và B cùng cập nhật, A ghi DB trước nhưng B cập nhật cache trước, dẫn đến cache chứa giá trị cũ của B. Xóa cache thì yêu cầu đọc tiếp theo sẽ load lại từ DB, tự nhiên tránh được vấn đề này.

3.2 Phân DB/phân bảng

Khi số lượng dữ liệu một bảng vượt quá mười triệu, hoặc QPS một DB vượt quá giới hạn, thì cần cân nhắc phân DB/phân bảng.

Chiến lượcCách làmƯu điểmNhược điểm
Phân DB dọcPhân tách DB theo domain nghiệp vụTách biệt nghiệp vụ, mở rộng độc lậpJOIN liên DB khó khăn
Phân bảng ngangCùng một bảng chia thành nhiều bảng theo quy tắcLượng dữ liệu một bảng kiểm soát đượcLựa chọn shard key rất quan trọng
Phân bảng dọcTách các trường lớn sang bảng độc lậpGiảm IO, nâng cao hiệu suất truy vấnCần JOIN thêm

Nguyên tắc chọn shard key:

  • Chọn trường được query thường xuyên nhất (ví dụ user_id)
  • Phân bố dữ liệu phải đồng đều, tránh điểm nóng
  • Cố gắng để dữ liệu cùng một người dùng ở cùng một shard (giảm truy vấn xuyên shard)

3.3 Message Queue

Message queue là "bộ giảm xóc" của hệ thống phân tán, vai trò cốt lõi là tách biệt, bất đồng bộ, cắt đỉnh lấp vực.

Kịch bảnKhông dùng queueDùng queue
Gửi thông báo sau khi đặt hàngAPI đặt hàng gọi đồng bộ service thông báo, thông báo lỗi dẫn đến đặt hàng lỗiĐặt hàng thành công thì gửi message, service thông báo tiêu thụ bất đồng bộ
Flash saleLưu lượng tức thời đánh sập DBYêu cầu vào queue trước, backend tiêu thụ theo năng lực
Đồng bộ dữ liệuService A gọi trực tiếp API của Service BService A phát sự kiện, Service B subscribe xử lý

4. Tư duy đánh đổi: Không có viên đạn bạc

Bản chất của thiết kế kiến trúc là đánh đổi (Trade-off). Mỗi quyết định đều có cái giá, điều quan trọng là hiểu cái giá đó và đưa ra lựa chọn phù hợp với giai đoạn hiện tại.

Chiều đánh đổiLựa chọn ALựa chọn BCơ sở quyết định
Nhất quán vs Khả dụngNhất quán mạnh (CP)Khả dụng cao (AP)Nghiệp vụ có chấp nhận không nhất quán tạm thời không?
Hiệu suất vs Chi phíCache toàn bộCache theo nhu cầuLượng dữ liệu và ngân sách
Đơn giản vs Linh hoạtKiến trúc monolithMicroservicesQuy mô đội nhóm và độ phức tạp nghiệp vụ
Thời gian thực vs BatchXử lý streamXử lý batchYêu cầu tính thời sự của dữ liệu
Tự xây vs Quản lý hộTự dựng MySQLDùng cloud database RDSNăng lực vận hành và chi phí

Architecture Decision Record (ADR)

Mỗi quyết định kiến trúc quan trọng đều nên được ghi lại: Bối cảnh là gì, đã cân nhắc những phương án nào, tại sao chọn cái này, có cái giá gì. Đây không phải để đổ lỗi, mà để những người đến sau hiểu "tại sao thời điểm đó lại thiết kế như vậy".

Format rất đơn giản:

  • Tiêu đề: Dùng XXX thay cho YYY
  • Bối cảnh: Chúng ta gặp vấn đề gì
  • Quyết định: Chúng ta chọn phương án nào
  • Lý do: Tại sao chọn phương án này
  • Cái giá: Nhược điểm và rủi ro của quyết định này

Các đánh đổi sai lầm phổ biến

Sai lầmBiểu hiệnCách làm đúng
Tối ưu quá sớmDAU 1000 đã áp dụng phân DB/phân bảngDùng DB đơn trước, gặp giới hạn mới tách
Bị công nghệ dẫn dắt"Tôi muốn dùng Kafka" thay vì "Tôi cần bất đồng bộ"Xuất phát từ vấn đề, không xuất phát từ công nghệ
Bỏ qua chi phí vận hànhChọn phương án tối ưu nhưng team không bảo trì đượcPhương án phải phù hợp với năng lực đội nhóm
Theo đuổi nhất quán hoàn hảoTất cả kịch bản đều dùng giao dịch phân tánHầu hết kịch bản nhất quán cuối cùng là đủ

5. Kịch bản kinh điển

Thông qua ba kịch bản kinh điển, kết nối các phương pháp luận đã học ở trên.

Dịch vụ short link là đề kinh điển trong phỏng vấn thiết kế hệ thống, tuy nhỏ nhưng đầy đủ các yếu tố.

Làm rõ nhu cầu:

  • Chức năng cốt lõi: Long link → Short link (ghi), Short link → Redirect (đọc)
  • Tỷ lệ đọc/ghi: Khoảng 100:1 (đọc nhiều hơn ghi rất nhiều)
  • Redirect trung bình mỗi ngày: 100 triệu lần
  • Short link không bao giờ hết hạn

Ước tính dung lượng:

Chỉ sốTính toánKết quả
Ghi QPS100 triệu / 100 / 86400≈ 12 QPS
Đọc QPS100 triệu / 86400≈ 1.200 QPS
Đọc QPS đỉnh1.200 x 3≈ 3.600 QPS
Lưu trữ 5 năm1 triệu/ngày x 365 x 5 x 100B≈ 18 GB
Cache (20%)18 GB x 20%≈ 3.6 GB

Thiết kế kiến trúc:

Đường ghi: Client → API Server → ID Generator → Base62 Encode → Ghi MySQL + Redis
Đường đọc: Client → CDN → API Server → Redis Query → 302 Redirect
                                    ↓ (cache miss)
                                  MySQL Query → Điền lại Redis

Quyết định thiết kế quan trọng:

  • Tạo short code: Snowflake distributed ID + Base62 encode, tránh hash collision
  • Chiến lược cache: Cache-Aside, short link nóng dùng CDN tăng tốc
  • Cơ sở dữ liệu: Đơn bảng là đủ (18GB rất nhỏ), tạo index theo short code

5.2 Hệ thống Feed Stream

Feed stream của nền tảng xã hội (Moments, trang chủ Weibo) là một đề kinh điển khác.

Thách thức cốt lõi: Người dùng đăng một bài viết, làm sao để tất cả người theo dõi đều thấy?

Phương ánCách làmƯu điểmNhược điểm
PullTổng hợp bài viết của người theo dõi theo thời gian thực khi đọcGhi đơn giản, ít lưu trữĐọc chậm, trễ cao khi theo dõi nhiều
PushGhi vào hộp thư đến của tất cả follower khi đăngĐọc cực nhanhNgười nổi tiếng đăng bài gây lan truyền ghi nghiêm trọng
Push + Pull kết hợpNgười thường push, người nổi tiếng pullCân bằng hiệu suất đọc ghiTriển khai phức tạp

Phương án Push + Pull kết hợp:

  • Số follower < 10.000: Khi đăng, push vào cache Feed của tất cả follower (mô hình push)
  • Số follower > 10.000: Không push, follower đọc theo thời gian thực khi mở (mô hình pull)
  • Khi người dùng mở Feed: Gộp nội dung đã push + nội dung pull theo thời gian thực từ người nổi tiếng, sắp xếp theo thời gian

5.3 Hệ thống Flash Sale

Thách thức cốt lõi của flash sale: đồng thời siêu cao trong tức thời + kho không được bán vượt.

Đặc trưng lưu lượng:

  • Trước khi sự kiện bắt đầu: Lượng lớn người dùng refresh trang chờ đợi
  • Khi sự kiện bắt đầu: QPS có thể gấp hơn 100 lần bình thường
  • Sau khi sự kiện kết thúc: Lưu lượng nhanh chóng giảm

Chiến lược cắt đỉnh phân tầng:

Yêu cầu người dùng → CDN (trang tĩnh) → Gateway (giới hạn tốc độ) → Message Queue (cắt đỉnh) → Inventory Service (trừ kho)
TầngChiến lượcHiệu quả
FrontendVô hiệu hóa nút + Trễ ngẫu nhiên + CAPTCHALọc bot, phân tán yêu cầu
CDNCache tài nguyên tĩnhGiảm 90% yêu cầu trang
GatewayToken bucket rate limitingChỉ cho qua lưu lượng hệ thống chịu được
Message QueueYêu cầu vào queue, xử lý bất đồng bộCắt đỉnh lấp vực, bảo vệ DB
Inventory ServicePre-deduct Redis + Thao tác nguyên tử LuaNgăn bán vượt, phản hồi cấp millisecond

Nguyên tắc cốt lõi của flash sale

  1. Chặn ở thượng lưu càng nhiều càng tốt: Có thể chặn ở CDN thì không để đến tầng ứng dụng
  2. Tách đọc ghi: Trang chi tiết sản phẩm đi qua cache, chỉ đặt hàng đi qua DB
  3. Xử lý bất đồng bộ: Người dùng nhấp "mua nhanh" rồi ngay lập tức trả về "đang xếp hàng", backend xử lý bất đồng bộ
  4. Phương án dự phòng: Rate limiting, circuit breaker, downgrade, bất kỳ tầng nào có vấn đề đều có Plan B

Tổng kết

Thiết kế hệ thống là một kỹ năng mang tính thực hành cao, cốt lõi nằm ở tư duy có cấu trúc và sự đánh đổi.

Ôn lại các điểm chính của chương này:

  1. Khung bốn bước: Làm rõ nhu cầu → Ước tính dung lượng → Thiết kế kiến trúc → Đi sâu tối ưu, mỗi bước đều không thể bỏ qua
  2. Ước tính mặt sau phong bì: Không cần chính xác, chỉ cần biết bậc lượng, dùng để hướng dẫn quyết định kiến trúc
  3. Mẫu cốt lõi: Cache, phân DB/phân bảng, message queue, CDN, rate limiting/circuit breaker — đây là những "khối xây" của thiết kế hệ thống
  4. Tư duy đánh đổi: Không có phương án hoàn hảo, chỉ có phương án phù hợp với giai đoạn hiện tại, ghi lại lý do và cái giá của mỗi quyết định
  5. Kịch bản kinh điển: Dịch vụ short link luyện cơ bản, Feed stream luyện mô hình push/pull, Flash sale luyện đồng thời cao — nắm vững ba cái này có thể áp dụng linh hoạt

Đọc thêm