Chương 14 – Case Studies: Ráp toàn bộ kiến thức vào hệ thống thật

Mỗi case study dưới đây là một bài tập tổng hợp: kiến trúc → vì sao → trade-off → failure case → bottleneck → cách mở rộng. Số chương trong ngoặc trỏ về lý thuyết tương ứng. Các con số là ước lượng để tập tư duy định lượng — thói quen quan trọng nhất khi thiết kế hệ thống. 1. URL Shortener — bài học vỡ lòng nhưng đủ cả trade-off Bài toán: 100M link mới/tháng (~40 write/s), redirect 10K/s — read:write = 250:1, latency redirect phải <50ms. ...

July 9, 2026 · 17 min

Chương 13 – Multi-region & Disaster Recovery: Bài toán Principal-level

1. Problem Statement Ba lực đẩy một hệ thống ra nhiều region: (1) Latency — tốc độ ánh sáng: Singapore↔Frankfurt ~160ms RTT, không tiền nào mua nhanh hơn được, user xa DC là UX tệ; (2) Disaster Recovery — cả một region có thể chết (AWS us-east-1 đã nhiều lần chứng minh), và với một số nghiệp vụ/regulator, “chúng tôi phụ thuộc một region” là câu trả lời không được chấp nhận; (3) Data residency — luật (GDPR, nghị định địa phương hóa dữ liệu) buộc dữ liệu công dân nằm trong biên giới. ...

July 9, 2026 · 13 min

Chương 12 – Time: "Bây giờ" là một khái niệm nguy hiểm

1. Problem Statement Trên một máy, now() có một giá trị và các sự kiện có thứ tự hiển nhiên. Trong hệ phân tán, mỗi node có đồng hồ riêng, trôi khác nhau, và câu hỏi tưởng tầm thường — sự kiện A ở node 1 xảy ra trước hay sau sự kiện B ở node 2? — trở nên không trả lời được bằng timestamp. Trong khi đó, hàng loạt cơ chế lại đang ngầm dựa vào timestamp: Last-Write-Wins (chương 05), TTL/lease (chương 07), log ordering, cronjob phối hợp, phát hiện timeout, chứng từ giao dịch. ...

July 9, 2026 · 12 min

Chương 11 – Reliability Patterns: Sống sót giữa những dependency đang hỏng

1. Problem Statement Chương 01 đã chứng minh: ở quy mô đủ lớn, luôn có thứ gì đó đang hỏng. Chương này trả lời câu hỏi tiếp theo: làm sao để một thành phần hỏng không kéo sập cả hệ — vì trong hệ phân tán, failure mode nguy hiểm nhất không phải là hỏng, mà là hỏng lan truyền (cascading failure): DB chậm (từ 5ms → 500ms) → connection pool của Service B cạn (request giữ connection lâu 100x) → thread của Service A chờ B, cạn thread pool → A timeout → client RETRY → tải TĂNG GẤP ĐÔI đúng lúc yếu nhất → toàn hệ sập, dù thứ hỏng ban đầu chỉ là MỘT query thiếu indexChuỗi trên là kịch bản sự cố phổ biến nhất trong microservices — mọi pattern của chương này (timeout, retry có kỷ luật, circuit breaker, bulkhead, backpressure, rate limiting) tồn tại để cắt đứt từng mắt xích của nó. Điểm chung của cả chương: hệ thống phải được thiết kế để từ chối bớt việc một cách có chủ đích, thay vì nhận hết rồi chết cùng nhau. ...

July 9, 2026 · 13 min

Chương 10 – Distributed Cache: Nhanh hơn, và những cách nó phản bội bạn

1. Problem Statement Database là thành phần đắt nhất và khó scale nhất (chương 05–06). Trong khi đó read:write điển hình là 100:1 và phần lớn read lặp lại trên một nhóm nhỏ key (power law). Cache khai thác sự lặp lại đó: trả lời từ RAM (~100µs qua mạng nội bộ, ~100ns local) thay vì disk + query planner (~1–50ms), chặn 90–99% read trước khi chạm DB. Nếu không có cache ở quy mô lớn: DB cần gấp 10–100 lần capacity — có khi bất khả thi về vật lý chứ không chỉ tiền. Nhưng cache về bản chất là một replica eventual-consistency tự chế, không có replication protocol tử tế — và vì thế toàn bộ chương 03/05 quay lại ám bạn dưới các cái tên mới: stale read, invalidation race, stampede, avalanche. Có câu đùa nghiêm túc: “Chỉ có hai bài toán khó trong khoa học máy tính: cache invalidation và đặt tên.” ...

July 9, 2026 · 13 min

Chương 09 – Event-driven Architecture: Sự kiện là hạng nhất

1. Problem Statement Khi “đơn hàng được tạo” cần kích hoạt 8 việc (email, tồn kho, loyalty, analytics, fraud, shipping…), mô hình gọi-trực-tiếp buộc OrderService biết và gọi cả 8 — mỗi consumer mới là một lần sửa OrderService, availability của việc tạo đơn phụ thuộc cả 8 hệ phụ trợ, và latency cộng dồn. Nghiêm trọng hơn ở tầng tổ chức: team Order thành nút cổ chai của mọi team khác. ...

July 9, 2026 · 11 min

Chương 08 – Distributed Transactions: Nhiều node, một nghiệp vụ nguyên tử

1. Problem Statement Nghiệp vụ “đặt hàng” chạm 3 hệ: trừ tồn kho (Inventory DB), tạo đơn (Order DB), trừ tiền (Payment service). Trên một database, BEGIN...COMMIT cho tất cả-hoặc-không. Khi dữ liệu đã tách (vì sharding — chương 06, vì microservices), không còn transaction chung — và mọi kịch bản dở dang trở nên khả thi: trừ tiền rồi mà không có đơn; giữ chỗ tồn kho rồi mà thanh toán fail và không ai nhả. ...

July 9, 2026 · 12 min

Chương 07 – Consensus: Làm sao nhiều máy nhất trí một điều

1. Problem Statement Nhiều bài toán ở các chương trước đều quy về một câu hỏi: làm sao một nhóm node, trên mạng không đáng tin cậy, nhất trí về MỘT giá trị — ai là leader (chương 05 failover), thứ tự các write trong log, bản đồ partition→node (chương 06), ai giữ lock. Nếu giải sai: split brain — hai node cùng tin mình là leader, cùng nhận write → hai nhánh sự thật phân kỳ, và không có cách nào hợp nhất tự động dữ liệu ledger đã phân kỳ. Đây là failure mode đắt nhất của hệ phân tán. Giải pháp cũ — “để con người quyết” — có MTTR hàng giờ; “node nào nhanh hơn thì thắng” — chính là split brain. ...

July 8, 2026 · 12 min

Chương 06 – Partitioning / Sharding: Chia dữ liệu để scale write

1. Problem Statement Replication (chương 05) nhân bản toàn bộ dữ liệu — giải quyết availability và scale read, nhưng mỗi node vẫn phải chứa hết dữ liệu và nhận hết write. Khi dataset vượt dung lượng một máy (chục TB) hoặc write throughput vượt khả năng một leader, con đường duy nhất: chia dữ liệu thành các partition (shard), mỗi node giữ một phần. Nếu không partition: disk đầy (hard stop), write throughput chạm trần leader, index không vừa RAM → mọi query chậm dần, backup/restore lâu đến vô dụng. Giải pháp cũ — mua máy to hơn — chạm trần và đắt phi tuyến (chương 01). ...

July 8, 2026 · 11 min

Chương 05 – Replication: Nhiều bản sao, một sự thật (hoặc không)

1. Problem Statement Replication = giữ cùng dữ liệu trên nhiều node. Ba lý do buộc phải làm: sống sót khi node chết (durability + availability), scale read (dàn read ra nhiều replica), giảm latency theo địa lý (bản sao gần user). Nếu không replicate: node chết = mất dữ liệu + downtime đến khi restore từ backup (RPO = từ lần backup cuối, RTO = hàng giờ). Backup không thay thế replication — backup cứu bạn khỏi mất vĩnh viễn, replication cứu bạn khỏi ngừng phục vụ. ...

July 8, 2026 · 11 min

Chương 04 – CAP & PACELC: Hiểu đúng, dùng đúng, và biết giới hạn

1. Problem Statement Khi thiết kế hệ thống có replication, sớm muộn bạn phải trả lời: khi mạng giữa các replica đứt (network partition), hệ thống làm gì? Từ chối phục vụ để giữ dữ liệu đúng, hay tiếp tục phục vụ và chấp nhận dữ liệu phân kỳ? CAP Theorem là công cụ tư duy chuẩn hóa cho câu hỏi đó — nhưng nó cũng là định lý bị hiểu sai nhiều nhất trong ngành, và hiểu sai dẫn đến quyết định kiến trúc sai (“chọn 2 trong 3” là cách đọc sai phổ biến nhất). ...

July 8, 2026 · 10 min

Chương 03 – Consistency Models: "Đọc thấy gì" là một hợp đồng

1. Problem Statement Ngay khi dữ liệu tồn tại ở hơn một nơi (replica, cache), xuất hiện câu hỏi không có ở hệ một máy: đọc ở nơi này có thấy cái vừa ghi ở nơi kia không? Consistency model là hợp đồng giữa hệ thống lưu trữ và ứng dụng: hệ thống cam kết trả lời câu hỏi đó theo quy tắc nào. Nếu không định nghĩa hợp đồng rõ ràng: user đăng comment, refresh trang, comment biến mất (đọc trúng replica trễ) → user đăng lại → duplicate; hệ thống kiểm tra số dư trên replica trễ → cho rút quá tiền; hai người cùng đặt phòng cuối cùng → double booking. Đây không phải bug hiếm — đây là hành vi mặc định khi bạn dùng replication mà không nghĩ về consistency model. ...

July 8, 2026 · 13 min

Chương 02 – Communication: Các node nói chuyện với nhau như thế nào

1. Problem Statement Trên một máy, module A gọi module B bằng một function call: chi phí ~nanosecond, không bao giờ “mất”, không bao giờ trả về hai lần, và nếu B crash thì A cũng crash cùng (trạng thái nhất quán). Khi B chuyển sang máy khác, function call trở thành remote call: chậm hơn ~10⁶ lần, có thể mất, có thể timeout khi đã thành công, và B chết không kéo A chết theo — nghe như ưu điểm, nhưng nghĩa là A phải tự quyết định làm gì khi không biết B sống hay chết. ...

July 8, 2026 · 13 min

Chương 01 – Foundations: Vì sao Distributed Systems tồn tại

1. Problem Statement Không ai muốn xây hệ thống phân tán. Hệ phân tán khó debug hơn, đắt hơn, nhiều chế độ lỗi hơn, và đòi hỏi đội ngũ giỏi hơn. Chúng ta xây hệ phân tán vì bị ép buộc bởi ba lực: Giới hạn vật lý của một máy — CPU, RAM, Disk IO, Network bandwidth đều có trần. Một máy 128 core, 4TB RAM vẫn là một máy. Single Point of Failure (SPOF) — một máy có xác suất hỏng khác 0. Khi nó hỏng, toàn bộ nghiệp vụ dừng. Không có cấu hình phần cứng nào loại bỏ được rủi ro này. Địa lý — người dùng ở Việt Nam gọi server ở Virginia chịu tối thiểu ~220ms round-trip. Tốc độ ánh sáng là giới hạn cứng, không mua được bằng tiền. Nếu không giải quyết: hệ thống sập khi traffic tăng, mất doanh thu khi máy hỏng, và trải nghiệm người dùng tệ ở xa datacenter. Giải pháp cũ (mua máy to hơn — Scale Up) chỉ trì hoãn vấn đề: giá tăng phi tuyến theo cấu hình, và SPOF vẫn nguyên vẹn. ...

July 8, 2026 · 15 min

Distributed Systems – Từ First Principles đến Production

Bộ tài liệu chuyên sâu về Hệ thống Phân tán, viết cho Backend Engineer, Senior Engineer, Tech Lead và Architect. Triết lý xuyên suốt: Business Growth → Single Machine → Single Point of Failure → Scalability Problem → Distributed Systems → New Problems → Trade-off → Solutions → Production. Cách đọc bộ tài liệu này Distributed Systems không phải là tập hợp các công nghệ như Kafka, Redis hay Kubernetes. Đó là một lĩnh vực nghiên cứu về cách nhiều máy tính phối hợp giải quyết một bài toán chung, trong khi luôn phải đối mặt với: độ trễ mạng không xác định, phần cứng hỏng bất kỳ lúc nào, phần mềm có bug, và sự thật khó chịu nhất — không node nào biết chắc trạng thái thật của node khác. ...

July 8, 2026 · 4 min