Problem-Driven System Design Framework

Tran Van Ngoc|

TL;DR

Problem-Driven System Design Framework là phương pháp thiết kế kiến trúc hệ thống dựa trên nhu cầu kinh doanh thực tế và tải hệ thống thực tế (Tư duy Tiến hóa Kiến trúc - Incremental / Evolutionary Architecture). Phương pháp này giúp triệt tiêu hoàn toàn sự quá tải nhận thức (Cognitive Overload) và cạm bẫy thiết kế thái quá (Over-Engineering) bằng cách đặt ra 4 câu hỏi bộ lọc trước khi quyết định áp dụng bất kỳ mẫu System Design nào.


Core Concept

1. Cạm bẫy “Thiết kế phòng bị thái quá”

  • Biểu hiện: Cố gắng áp dụng Caching, Microservices, Event-Driven, Distributed Locking cho một ứng dụng CRUD hoặc một tính năng chỉ phục vụ 100100 người dùng/ngày.
  • Hậu quả:
    • Gây quá tải bộ não (Cognitive Overload) vì phải dung nạp quá nhiều khái niệm trừu tượng cùng lúc.
    • Tốn 80%80\% thời gian cấu hình hạ tầng phức tạp thay vì tập trung vào giá trị cốt lõi của sản phẩm (Product Value).
    • Tăng độ phức tạp khi bảo trì và sửa lỗi (Debugging Friction).

2. Nguyên lý Tiến hóa Kiến trúc

Phục vụ ai? → Điểm vỡ ở đâu? → Áp dụng Pattern tối thiểu → Học Just-In-Time

Một kiến trúc tốt KHÔNG PHẢI là kiến trúc phức tạp nhất ngay từ ngày đầu tiên, mà là kiến trúc phù hợp nhất với giai đoạn hiện tại và dễ dàng mở rộng khi đạt ngưỡng tải mới.


Practical Implementation

️ Khung 4 Câu Hỏi Bộ Lọc System Design

Khi vừa làm dự án vừa chuẩn bị thiết kế một tính năng mới, hãy dừng lại 2 phút và tự vấn 4 câu hỏi theo thứ tự:

graph TD
    Q1[1. Tính năng này phục vụ ai & Tải thực tế là bao nhiêu?] -->|Tải nhỏ/CRUD| Plain[Code Đơn Giản: Monolith + Single DB]
    Q1 -->|Tải cao/Tính năng nhạy cảm| Q2[2. Điểm vỡ failure point sẽ xảy ra ở đâu?]
    Q2 --> Q3[3. Mốc giải quyết tối thiểu nào là hợp lý?]
    Q3 --> Q4[4. Tra cứu & Học Pattern đó JUST-IN-TIME]

Câu hỏi 1: Tính năng này phục vụ ai & Tải thực tế là bao nhiêu?

  • Phân tích: Nếu tính năng chỉ dùng cho Admin nội bộ (ví dụ: Tạo bài viết, Xem báo cáo) → Tải 10−5010-50 req/ngày.
  • Quyết định: KHÔNG DÙNG SYSTEM DESIGN PHỨC TẠP! Dùng 1 Controller + 1 SQL Query đơn giản. Hoàn thành nhanh nhất có thể.

Câu hỏi 2: Điểm vỡ nằm ở đâu khi lượng người dùng tăng?

  • Phân tích: Nếu là tính năng Thanh toán / Đặt vé xem phim (Flash sale) → Tải 5.0005.000 req/giây vào đúng 12:00 trưa.
  • Điểm vỡ dự đoán:
    1. Database Read bị sập vì quá nhiều connection hỏi thông tin lịch chiếu.
    2. Database Write bị Race Condition (2 người đặt trùng 1 ghế).

Câu hỏi 3: Mốc giải quyết từ từ là gì?

Không giải quyết tất cả cùng lúc! Chia ra các mốc nâng cấp:

  • Mốc 1 (MVP): Viết code chạy đúng logic nghiệp vụ trên DB đơn lẻ. Thêm Pessimistic Lock (SELECT FOR UPDATE) để chống đặt trùng ghế.
  • Mốc 2 (Khi DB Read bị nghẽn): Thêm tầng Redis Cache-Aside cho API lấy danh sách phim.
  • Mốc 3 (Khi gửi Mail/SMS xác nhận quá chậm): Tách việc gửi Mail ra chạy ngầm bằng Outbox Pattern + Message Queue.

Câu hỏi 4: Học kiến trúc đúng lúc

  • Chỉ mở sách/video ra tìm hiểu sâu về Outbox Pattern khi mày chạm tới Mốc 3.
  • Lúc này, bộ não đã hiểu rõ lý do vì sao cần Outbox Pattern, giúp tiếp thu kiến thức cực kỳ sắc bén và không bao giờ bị quên.