Reliability — fault vs failure và sức mạnh của dư thừa
Hệ tin cậy không phải hệ không bao giờ lỗi, mà là hệ mà fault (lỗi bộ phận) không thành failure (sập toàn cục). Fault vs failure, ba loại fault, fault tolerance.
TL;DR: Reliability là khả năng hệ tiếp tục làm đúng việc ngay cả khi có trục trặc. Điểm mấu chốt là phân biệt fault (một bộ phận lệch khỏi spec — một đĩa hỏng, một node treo) với failure (cả hệ ngừng phục vụ người dùng). Mục tiêu không phải loại bỏ mọi fault — điều bất khả — mà là thiết kế để fault không leo thang thành failure (fault tolerance), chủ yếu bằng dư thừa (redundancy). Fault có ba nguồn: phần cứng, phần mềm, và con người; nghịch lý là con người và lỗi phần mềm (tương quan, lan rộng) thường nguy hiểm hơn phần cứng (ngẫu nhiên, độc lập).
Khi một dịch vụ "sập", câu hỏi đầu tiên của người mới là "làm sao để không bao giờ lỗi?". Đó là câu hỏi sai. Đĩa sẽ hỏng, mạng sẽ chớp, người vận hành sẽ gõ nhầm lệnh — xác suất mỗi thứ nhỏ, nhưng ở quy mô hàng nghìn máy thì mỗi ngày đều có cái gì đó hỏng. Hệ tin cậy không phải hệ may mắn không gặp trục trặc; nó là hệ mà trục trặc bộ phận được nuốt gọn trước khi người dùng kịp thấy.
Bài này tách bạch hai khái niệm hay bị gộp làm một — fault và failure — rồi chỉ ra vì sao thêm bản dư thừa (nghe như lãng phí) lại là cách chính để tăng độ tin cậy.
1. Analogy — máy bay bốn động cơ
Một máy bay chở khách có thể bay tiếp khi một động cơ chết giữa chuyến. Không phải vì động cơ không bao giờ hỏng — mà vì nhà thiết kế giả định nó sẽ hỏng và đặt dư động cơ, cùng quy trình để phi công xử lý. Động cơ hỏng là một fault; chuyến bay vẫn hạ cánh an toàn nghĩa là fault đó không trở thành failure.
Ngược lại, nếu cả bốn động cơ dùng chung một thùng nhiên liệu nhiễm bẩn, thì "bốn động cơ" chẳng giúp gì — chúng hỏng cùng lúc, cùng nguyên nhân. Redundancy chỉ cứu được khi các bản hỏng độc lập.
| Máy bay | Hệ dữ liệu |
|---|---|
| Một động cơ chết giữa chuyến | Fault — một node/đĩa lỗi |
| Chuyến bay vẫn hạ cánh an toàn | Fault được nuốt, không thành failure |
| Cả 4 động cơ chết → rơi | Failure — hệ ngừng phục vụ |
| Dư động cơ + quy trình phi công | Fault tolerance (redundancy + xử lý) |
| Chung thùng nhiên liệu bẩn | Fault tương quan — redundancy vô dụng |
Fault là "một động cơ chết", failure là "máy bay rơi". Cả track này là nghệ thuật giữ cho fault đừng biến thành failure.
2. Fault vs failure — khác nhau ở đâu?
Hai từ nghe gần giống nhau nhưng ở hai tầng khác nhau:
- Fault — một bộ phận của hệ lệch khỏi spec: một ổ đĩa trả về bit sai, một node ngừng phản hồi, một gói tin rớt. Fault là cục bộ.
- Failure — cả hệ ngừng cung cấp dịch vụ mà người dùng cần: API trả lỗi, dữ liệu không đọc được. Failure là toàn cục, là thứ người dùng thấy.
Quan hệ giữa chúng chính là chỗ để thiết kế: một fault có thể dẫn tới failure, nhưng không nhất thiết. Một hệ tin cậy chèn "lớp đệm" giữa hai tầng.

Vì không thể đưa xác suất fault về 0, reliability được định nghĩa qua vế phải: giảm tỉ lệ fault leo thang thành failure. Đây là lý do ta đo reliability bằng những đại lượng như thời gian giữa hai lần failure, chứ không phải "số fault" — fault xảy ra liên tục là chuyện bình thường.
3. Ba loại fault — và cái nào đáng lo hơn
Fault phần cứng — đĩa hỏng, RAM lỗi bit, mất điện, đứt cáp. Đặc tính: phần lớn ngẫu nhiên và độc lập — đĩa này hỏng không kéo đĩa kia hỏng theo. Vì độc lập, redundancy xử rất tốt: RAID nhiều đĩa, nhiều nguồn điện, nhiều máy. Đây là loại fault "dễ" nhất.
Fault phần mềm — một bug bị kích khi gặp input đặc biệt, memory leak, một service làm chậm kéo cả chuỗi. Đặc tính: tương quan — cùng một bug nằm trong mọi bản chạy cùng phiên bản, nên khi nó bùng, nó quật ngã cả đàn cùng lúc. Redundancy kiểu "chạy 5 bản giống hệt" không cứu được, vì cả 5 bản cùng dính.
Fault con người — cấu hình sai, gõ nhầm lệnh xoá, triển khai nhầm bản. Đặc tính: trong thực tế đây là nguồn sự cố lớn nhất. Con người vận hành sai nhiều hơn phần cứng tự hỏng.
Trực giác nói phần cứng đáng lo nhất. Thực tế ngược: fault phần cứng độc lập nên redundancy nuốt gọn; còn fault phần mềm và con người đánh trúng mọi bản cùng lúc, nên nhân bản số lượng không giúp. Vì vậy độ tin cậy thật sự đến từ cả giảm fault tương quan (test, rollout từ từ, giao diện vận hành khó gõ nhầm) chứ không chỉ "thêm máy".
4. Fault tolerance — chặn fault leo thang bằng dư thừa
Fault tolerance là năng lực giữ hệ chạy đúng dù có fault. Cơ chế chính là redundancy: có sẵn bản dự phòng để khi một bản fault, bản khác gánh ngay.
Ba bản dự phòng độc lập, mỗi bản có xác suất hỏng 1% trong một tháng. Đoán trước khi đọc tiếp: xác suất cả ba cùng hỏng trong tháng đó rơi vào cỡ nào — khoảng 3%, 0,01%, hay 0,0001%? Bám vào chữ "độc lập" để chọn.
Nguyen ly redundancy (chi cuu duoc khi cac ban HONG DOC LAP):
request --> [ ban A ] (fault: A chet)
--> [ ban B ] (con song -> ganh)
--> [ ban C ] (con song)
P(ca he sap) = P(A chet) x P(B chet) x P(C chet) -- neu doc lap
=> nhan cac xac suat nho lai -> rat nho
Sức mạnh nằm ở phép nhân: nếu mỗi bản có xác suất hỏng nhỏ và độc lập, xác suất tất cả cùng hỏng là tích các số nhỏ đó — nhỏ đi rất nhanh. Lấy đúng ví dụ vừa đoán: ba bản độc lập, mỗi bản hỏng 1% (0,01) một tháng, thì cả ba cùng hỏng chỉ còn 0,01 × 0,01 × 0,01 = 0,000001, tức 0,0001% — nhỏ hơn rủi ro một bản đơn tới bốn bậc độ lớn. Nhưng phép nhân này chỉ đúng khi độc lập. Nếu ba bản dùng chung một điểm chết (cùng nguồn điện, cùng bug, cùng lệnh sai), chúng hỏng tương quan và phép nhân sụp đổ — đây là lý do thiết kế phải săn tìm và loại single point of failure (điểm chết chung).
Cơ chế bên dưới của "tương quan" cũng đo được. Giả sử ba bản dùng chung một thành phần có xác suất hỏng q (một switch mạng, một nguồn điện): khi thành phần chung đó chết, cả ba chết cùng lúc — nên xác suất cả hệ sập không bao giờ nhỏ hơn q, dù thêm bao nhiêu bản. Redundancy chỉ kéo được phần rủi ro độc lập xuống gần 0; phần dùng chung đặt một cái sàn mà nhân bản số lượng không vượt qua nổi. Vì thế việc thật của thiết kế fault-tolerant là hạ chính cái q đó — tách nguồn điện, tách switch, đa dạng phiên bản — chứ không chỉ tăng số bản.
Cả track sau đây, khi bạn học replication (nhân bản dữ liệu ra nhiều node), thực chất là học cách hiện thực redundancy cho dữ liệu — và phần khó nhất luôn là giữ các bản độc lập và nhất quán đủ mức.
5. Pitfall — theo đuổi "không lỗi" thay vì "chịu lỗi"
Sai lầm hay gặp: đội kỹ thuật đổ công sức để một thành phần "không bao giờ hỏng" — mua phần cứng đắt nhất, viết code phòng thủ mọi input — nhưng bỏ quên lớp chịu lỗi ở tầng hệ thống.
❌ Tu duy sai: "lam server nay that ben de no khong bao gio down"
-> van la MOT server -> single point of failure -> 1 fault = failure
✅ Tu duy dung: "gia dinh server SE down, dat 2-3 ban doc lap + tu dong failover"
-> 1 fault duoc nuot -> khong thanh failure
Hệ quả: khi thành phần "bất khả xâm phạm" đó cuối cùng cũng hỏng (nó sẽ hỏng), không có gì đỡ — một fault thành failure toàn cục. Ngoài ra, nỗ lực này thường bỏ qua fault con người (nguồn sự cố lớn nhất): server bền tới đâu cũng không chống được một lệnh DELETE gõ nhầm.
Hướng đúng: giả định mọi thành phần sẽ fault, rồi thiết kế để fault được nuốt — redundancy độc lập, failover tự động, rollout từ từ để bắt bug sớm, và giao diện vận hành khó gây lỗi. Đo reliability ở mức hệ thống (người dùng có bị gián đoạn không), không ở mức linh kiện (con chip này bền bao lâu).
6. 📚 Đào sâu — nguồn gốc & tài liệu
- Designing Data-Intensive Applications (Kleppmann) — Chương 1 "Reliable, Scalable, and Maintainable Applications" — mục "Reliability": định nghĩa fault (một bộ phận lệch spec) vs failure (cả hệ ngừng phục vụ), phân loại hardware/software/human fault, và vì sao fault tolerance quan trọng hơn "no fault". Định nghĩa 2 tầng fault/failure ở bài này theo đúng cách Kleppmann trình bày.
- Học thuật gốc: Avizienis, Laprie, Randell & Landwehr (2004), "Basic Concepts and Taxonomy of Dependable and Secure Computing" — mô tả một chuỗi 3 tầng chi tiết hơn: fault (nguyên nhân tiềm ẩn) → error (trạng thái hệ sai lệch do fault kích hoạt) → failure (hệ ngừng phục vụ đúng cách). Bài này lược tầng "error" ở giữa cho gọn, dùng khung 2 tầng của DDIA làm chính.
Ghi chú: DDIA Ch1 là nguồn agnostic chuẩn cho ba thước đo reliability/scalability/maintainability; cách "giả định fault, thiết kế để chịu" là tinh thần xuyên suốt các chương sau về replication và fault trong hệ phân tán.
7. Liên hệ các bài khác
- Bài 02 — Scalability: reliability trả lời "hệ có sai không", scalability trả lời "hệ chịu được bao nhiêu tải" — hai thước đo song song, đọc tiếp để có cả cặp.
- Bài 03 — Tail latency: một hệ "còn sống" nhưng chậm ở đuôi (p99 cao) vẫn là trải nghiệm tệ — mặt định lượng của "phục vụ đúng".
- Bài 04 — Maintainability: fault con người (nguồn sự cố lớn nhất) được giảm chủ yếu bằng operability tốt — nối thẳng sang bài maintainability.
8. Tóm tắt
- Fault (bộ phận lệch spec) khác failure (cả hệ ngừng phục vụ); mục tiêu là chặn fault leo thang thành failure, không phải diệt hết fault.
- Redundancy là đòn chính: xác suất mọi bản cùng hỏng = tích các xác suất nhỏ — chỉ khi các bản hỏng độc lập.
- Single point of failure (điểm chết chung) phá vỡ tính độc lập → phải săn và loại bỏ.
- Ba loại fault: phần cứng (ngẫu nhiên, độc lập — redundancy xử tốt), phần mềm (tương quan, quật cả đàn), con người (nguồn sự cố lớn nhất).
9. Tự kiểm tra
- Q1Phân biệt fault và failure. Vì sao một hệ tin cậy đặt mục tiêu ở việc chặn fault leo thang, chứ không phải loại bỏ mọi fault?
- Q2Vì sao redundancy (thêm bản dự phòng) chỉ tăng độ tin cậy khi các bản hỏng độc lập? Cho một ví dụ redundancy vô dụng.
- Q3Trong ba loại fault (phần cứng, phần mềm, con người), vì sao fault phần cứng lại 'dễ' xử hơn hai loại kia dù nghe có vẻ đáng lo nhất?
- Q4Một đội định mua server đắt nhất, bền nhất để 'nó không bao giờ down'. Vì sao đây là tư duy reliability sai, và nên thay bằng gì?
- Q5Vì sao 'single point of failure' là khái niệm trung tâm khi thiết kế fault tolerance, và nó liên quan thế nào tới giả định độc lập?
Bài tiếp theo: Scalability — mô tả tải bằng tham số
Bài này đáng gửi cho bạn học cùng?
Copy link đã gắn nguồn — dán group, chat, hoặc LinkedIn.
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
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