---
title: "Thiết kế dữ liệu phân tán - consistency, quorum, leader election và failover"
description: "Khóa học về dữ liệu phân tán cho app dùng Postgres có replica, xoay quanh câu hỏi bản sao nào đáng tin cậy. Bạn sẽ giải thích được replication lag, chọn nơi đọc cho từng trang, bầu leader an toàn và xử lý conflict khi ghi nhiều nơi. Nhờ đó, bạn chọn giải pháp kiến trúc dựa trên số đo thay vì phỏng đoán."
canonical: "https://200lab.io/courses/thiet-ke-du-lieu-phan-tan-consistency-quorum-leader-election-va-failover"
type: "course"
course_type: "course"
learning_type: "free_form"
published: "2026-10-10T05:00:10Z"
students: 26
---

## Khóa học này mang lại gì cho bạn

Ứng dụng bạn phát triển cùng AI agent ban đầu chỉ cần một Postgres duy nhất. Khi lưu lượng truy cập tăng lên, database được bổ sung read replica để gánh bớt tải đọc và làm bản sao dự phòng. Từ thời điểm dữ liệu nằm trên nhiều server, hệ thống bắt đầu xuất hiện những hành vi khó đoán: khách vừa thanh toán xong mở lịch sử lại không thấy đơn, hoặc khi primary chết, đội trực không thể xác định đã có bao nhiêu đơn hàng bị mất. Bảy năng lực thực tế dưới đây giúp bạn làm chủ các tình huống đó, đưa ra quyết định dựa trên số liệu và kiểm soát chặt chẽ các đề xuất kiến trúc từ agent.

- **Phân biệt** nguyên nhân gây mất kết nối giữa các node — Bạn giải thích được vì sao tiến trình crash, server quá tải hay network partition đều có cùng biểu hiện không phản hồi, từ đó chọn rule gỡ node cân bằng giữa gỡ nhầm và phát hiện chậm, đồng thời dùng Lamport clock thay cho đồng hồ máy tính để giữ đúng thứ tự nhân quả giữa các service.
- **Đo đạc** và kiểm soát replication lag — Bạn lần theo đường đi của lệnh ghi qua WAL để tìm đúng chặng bị nghẽn, chia nhỏ các batch job lớn để hạ lag cao điểm từ 95 giây xuống dưới 3 giây, và chọn đúng mức chờ replica cho từng transaction.
- **Quyết định** nơi đọc dữ liệu cho từng tính năng — Bạn phân biệt linearizable với eventual consistency trên lịch sử thao tác, giữ tính năng thu hồi phiên ở primary để chặn truy cập trái phép, và dùng mốc dữ liệu theo phiên để người dùng không gặp tình trạng số liệu bị nhảy lùi khi tải lại trang.
- **Thiết kế** cơ chế bầu primary mới an toàn — Bạn áp dụng leader election theo đa số phiếu với term tăng dần để ngăn chặn split brain, kết hợp lease và router kiểm tra term nhằm chặn primary cũ tiếp tục nhận lệnh ghi sau sự cố.
- **Xử lý** sự cố failover và phục hồi dữ liệu sai — Bạn chọn đúng replica thiếu ít dữ liệu nhất để promote khi primary chết, đưa primary cũ quay lại cụm qua pg_rewind mà không cần chép lại toàn bộ dữ liệu, và dùng logical repair để sửa đúng những dòng ghi sai thay vì đưa cả database về quá khứ.
- **Kiểm soát** conflict khi nhiều node cùng nhận lệnh ghi — Bạn phân định rõ ranh giới giữa leader-follower, multi-leader và leaderless replication, dùng version vector thay cho last-write-wins để không ghi đè dữ liệu, và nhận diện những invariant trên toàn cụm mà CRDT không thể tự bảo toàn.
- **Chất vấn** đề xuất hạ tầng của AI agent — Bạn đặt ra ba câu hỏi cốt lõi về số giây lag cao điểm, số lệnh ghi có nguy cơ mất và số node tham gia bỏ phiếu trước khi đồng ý áp dụng cấu hình tự động failover hay thêm replica.

Các ví dụ trong khóa học được triển khai trên nền Postgres với code TypeScript minh họa thực tế, không phụ thuộc vào một framework failover cụ thể.

## Khóa học cung cấp những nền tảng nào

Toàn bộ khóa học được xây dựng xoay quanh câu hỏi cốt lõi: khi dữ liệu nằm trên nhiều máy, bản ghi nào đáng tin và hệ thống dựa vào đâu để ra quyết định? Khi replication lag kéo dài, hai primary cùng nhận lệnh ghi hoặc hai kho hàng cùng sửa tồn kho của một sản phẩm, hệ thống phân tán đều đang mắc kẹt ở chính câu hỏi này. Bạn có thể đối chiếu các mô hình lỗi và cơ chế đồng thuận trong [bài giảng Distributed Systems của Martin Kleppmann](https://www.cl.cam.ac.uk/teaching/2526/ConcDisSys/dist-sys-notes.pdf), tham khảo kiến trúc nhân bản dữ liệu tại [tài liệu High Availability của PostgreSQL](https://www.postgresql.org/docs/current/high-availability.html), và xem các sự cố phân mảnh mạng thực tế qua bài viết [The network is reliable](https://aphyr.com/posts/288-the-network-is-reliable).

### 1. Node lỗi, network partition và đồng hồ của các máy lệch nhau
Chương mở đầu bằng bài toán phân biệt trạng thái của node khi failure detector ghi nhận 23 lần cảnh báo replica down trong một tuần, nhưng thực tế có tới 21 lần node vẫn chạy bình thường. Bạn sẽ phân tích vì sao timeout chỉ là một phỏng đoán không thể xác định chính xác giữa crash, nghẽn I/O hay network partition, từ đó thiết lập rule gỡ node dựa trên số lần lỗi liên tiếp để cân bằng giữa gỡ nhầm và thời gian phát hiện sự cố. Tiếp đó, bạn khám phá hiện tượng clock drift khiến đồng hồ server thanh toán chậm 1,3 giây làm màn hình tra cứu hiển thị bước “đã hoàn tiền” trước bước “đã hủy”. Bằng cách đưa bộ đếm Lamport clock vào từng message giữa các service, bạn khôi phục lại trật tự nhân quả chuẩn xác mà không cần phụ thuộc vào giờ hệ thống.

### 2. Replication lag và consistency khi đọc từ replica
Chương này đi sâu vào cơ chế replication bất đồng bộ và đồng bộ khi tách luồng đọc ghi. Bạn sẽ lần theo từng chặng của file WAL để hiểu vì sao một job tính điểm thưởng cập nhật 6 triệu dòng lại đẩy replication lag từ 0,5 giây lên 95 giây, đồng thời kiểm soát độ trễ p99 khi replica đồng bộ khởi động lại. Khi đọc từ replica, bạn sẽ dựng bảng lịch sử thao tác để thấy rõ lỗ hổng của eventual consistency khi phiên đăng xuất bị thu hồi trên primary nhưng điện thoại cũ vẫn gọi API thành công qua replica. Chương khép lại với giải pháp gắn mốc LSN vào phiên người dùng và bài toán tình huống thực tế giúp kéo tỉ lệ đơn trùng do khách tải lại trang từ 0,7% về mức nền 0,05%.

### 3. Chọn primary mới mà không để xảy ra split brain
Chương ba tập trung vào bài toán đồng thuận khi chọn node lãnh đạo cho cụm database. Bạn bắt đầu từ cơ chế phân quyền bằng lease và nguyên lý fencing token ở tầng lưu trữ để ngăn worker cũ ghi đè dữ liệu sau khi tiến trình bị tạm dừng. Tiếp đó, bạn phân tích sự cố một script watchdog tự ý promote node với một phiếu duy nhất khi network chập chờn, rồi thay thế bằng thuật toán leader election theo đa số phiếu với term tăng dần. Bạn cũng thiết lập lớp router đứng trước database để xác minh leader định kỳ, ngừng chuyển lệnh khi không xác minh được và đóng connection cũ khi áp dụng term mới, kết hợp lớp lease tại database để xử lý các lệnh đã lọt tới primary cũ.

### 4. Failover, failback và sửa dữ liệu bị ghi sai
Chương này trang bị quy trình xử lý trọn vẹn khi primary gặp sự cố phần cứng hoặc phần mềm. Bạn sẽ thiết lập tiêu chí promote replica dựa trên lượng WAL đã nhận thay vì thứ tự ưu tiên cố định, giúp giảm thiểu số đơn hàng bị mất từ 180 đơn xuống còn khoảng 9 đơn. Khi node cũ được sửa xong, bạn dùng pg_rewind với riêng công đoạn chép dữ liệu khác biệt chỉ mất 14 phút thay vì mất 3 giờ 20 phút chép lại toàn bộ 1,2 TB, sau đó cho node replay WAL để bắt kịp cụm trước khi tính là bản sao dự phòng, kết hợp quy trình switchover có kế hoạch để chuyển vai an toàn. Với sự cố ghi sai do con người hoặc script chạy nhầm điều kiện, bạn sẽ thực hiện logical repair từ một instance khôi phục riêng biệt để bảo toàn toàn bộ đơn hàng mới phát sinh.

### 5. Nhiều node cùng nhận lệnh ghi thì xử lý conflict thế nào
Chương cuối giải quyết bài toán khi một primary duy nhất không còn đáp ứng được yêu cầu nghiệp vụ tại các chi nhánh ngoại tuyến. Bạn sẽ phân loại dữ liệu theo nơi ghi để tránh phát sinh conflict ngay từ khâu thiết kế, đồng thời tính toán bộ thông số quorum W + R > N nhằm ngăn chặn giỏ hàng hiển thị lại món đã xóa trên hệ thống leaderless. Bạn cũng thấy rõ rủi ro mất dữ liệu của last-write-wins khi đồng hồ lệch để chuyển sang dùng version vector cho từng dòng dữ liệu. Cuối cùng, bạn xử lý các quy tắc nghiệp vụ vượt giới hạn bằng mô hình cấp phát hạn mức trước (escrow), khép lại bằng bài toán giải cứu hệ thống tồn kho đa chi nhánh sau 160 phút đứt kết nối qua network.

## Vì sao 200Lab tạo ra khóa học này

Ngày nay, việc dựng thêm một replica chỉ tốn vài cú nhấp chuột trên bảng điều khiển cloud hoặc một câu lệnh xác nhận theo gợi ý của AI agent. Cơ sở dữ liệu của bạn có thể vận hành trên nhiều máy từ rất sớm, trước khi đội ngũ kịp đo đạc xem replica đang chậm hơn bao nhiêu giây, và liệu bản sao đó có đủ dữ liệu để thay thế an toàn khi primary đột ngột dừng hoạt động hay không.

Phần lớn các sự cố trong hệ thống phân tán không để lại bất kỳ dòng log báo lỗi nào. Replication vẫn chạy, tiến trình failover báo thành công, các job đồng bộ hoàn tất bình thường, nhưng đơn hàng đã xác nhận với khách lại biến mất khỏi hệ thống, ghi chú của nhân viên bị xóa sạch và số liệu tồn kho lệch hoàn toàn so với thực tế trên kệ. Khi đó, kỹ sư vận hành phải đối mặt với áp lực đối soát từng giao dịch, giải thích sự mâu thuẫn dữ liệu và trực tiếp hoàn tiền cho khách hàng.

Thực tế này từng diễn ra ở những hệ thống quy mô lớn. GitLab từng gặp sự cố hai node cùng hoạt động như primary khiến đội ngũ phải chấp nhận bỏ toàn bộ các lệnh ghi trong khoảng 6 giờ trên một node. GitHub từng ghi nhận một đợt phân mảnh mạng kéo dài 43 giây khiến hệ thống chuyển nhầm primary MySQL sang data center khác, bỏ lại 954 lệnh ghi chưa kịp sao chép. Dù ở quy mô hàng nghìn server hay một app vừa có replica đầu tiên, gốc rễ vấn đề vẫn là sự thiếu hụt số liệu đo đạc độ trễ và thiếu cơ chế cô lập node cũ.

Khóa học giúp bạn làm chủ tư duy thiết kế trước khi sự cố xảy ra trên môi trường production. Mỗi vấn đề được mổ xẻ đến tận cùng của các quyết định kỹ thuật: đọc ở đâu, commit có chờ xác nhận hay không, thành phần nào chịu trách nhiệm chặn đường ghi cũ và dữ liệu nào được phép sửa đồng thời. Bạn sẽ tự tin bảo vệ giải pháp trước toàn đội ngũ bằng các phân tích tradeoff cụ thể, đồng thời kiểm soát các đề xuất từ AI agent bằng số liệu thay vì tiếp nhận mã nguồn một cách thụ động.

## Những vấn đề thường gặp khi thiết kế dữ liệu phân tán

Khi dữ liệu hiển thị không nhất quán, phản xạ phổ biến là tìm lỗi trong code xử lý giao diện hoặc vội vã tăng timeout và bổ sung cơ chế retry. Trong hệ thống có nhiều bản sao, nguyên nhân thường xuất phát từ việc lựa chọn sai node tiếp nhận lệnh, sự lệch pha giữa các bản sao và giả định thiếu căn cứ về tính sẵn sàng của dữ liệu.

- App báo replica down 23 lần một tuần khiến tải đọc dồn về làm primary chạm 88% CPU — Node vẫn chạy bình thường nhưng disk bận xả checkpoint định kỳ, khiến failure detector phán đoán sai do timeout quá nhạy.
- Khách vừa bấm đặt hàng xong mở trang lịch sử thì không thấy đơn nên bấm mua lại — Lệnh đọc chuyển hướng sang replica đang bị lag và hệ thống thiếu cơ chế định tuyến theo mốc LSN của phiên để giữ bảo đảm read-your-writes.
- Tài khoản đã bấm đăng xuất khỏi mọi thiết bị nhưng điện thoại bị mất vẫn gọi API thành công suốt gần 4 giây — Lệnh thu hồi phiên được commit trên primary nhưng tầng kiểm tra xác thực lại đọc từ replica bất đồng bộ vốn chưa kịp replay thay đổi.
- Primary bị treo toàn bộ lệnh ghi thanh toán suốt 7 phút giữa đêm — Cấu hình synchronous replication chỉ có duy nhất một replica đồng bộ, khiến primary bị nghẽn hoàn toàn khi replica đó khởi động lại để vá kernel.
- Script watchdog tự ý promote replica lên làm primary mới khi primary cũ vẫn đang nhận lệnh ghi bình thường — Hệ thống hai node đưa ra quyết định dựa trên số lần ping lỗi đơn độc thay vì yêu cầu đa số node bỏ phiếu trong một term xác định.
- Sau sự cố failover tự động, hệ thống đối soát phát hiện mất 180 đơn hàng đã báo thành công — Công cụ failover chọn node promote dựa theo thứ tự cấu hình tĩnh thay vì so sánh xem replica nào đã nhận nhiều WAL nhất tại thời điểm xảy ra sự cố.
- Một script cập nhật sai giá khiến đội ngũ định khôi phục cả database về thời điểm trước sự cố — Thao tác point-in-time recovery sẽ xóa sạch 2.300 đơn hàng hợp lệ phát sinh sau đó thay vì trích xuất giá cũ để chạy logical repair trên đúng các dòng bị ảnh hưởng.
- Job đồng bộ hai chiều âm thầm làm biến mất hơn 400 bản sửa địa chỉ và ghi chú giao hàng trong tháng — Cơ chế last-write-wins ghi đè toàn bộ dòng do hai nguyên nhân: timestamp lệch giữa các máy và các bản sửa đồng thời phát sinh khi chưa thấy nhau, thay vì so sánh version vector và gộp theo từng field.

Mỗi vấn đề trên đều được phân tích kèm dòng log, trace thực tế và giải pháp xử lý cụ thể trong các bài học của khóa.

## Bạn sẽ học theo cách nào

- **Khởi đầu từ triệu chứng kỹ thuật thực tế** — Bạn tiếp cận từng bài qua một sự cố rõ ràng trên dashboard, dòng log hệ thống hoặc kết quả đối soát dữ liệu thay vì các khái niệm lý thuyết trừu tượng.
- **Phân tích timeline và sơ đồ tương tác** — Bạn theo dõi đường đi của từng lệnh ghi qua WAL, nhịp trao đổi message giữa các service và thứ tự xen kẽ của các request chạy song song trên cùng một trục thời gian.
- **Đo đạc và cân nhắc tradeoff bằng số liệu** — Bạn tính toán các chỉ số RPO, RTO, độ trễ p99 và tỉ lệ gỡ nhầm để đưa ra lựa chọn kiến trúc phù hợp với từng nấc tăng trưởng của hệ thống.
- **Rèn luyện phản xạ qua tình huống dự đoán** — Bạn củng cố kiến thức bằng các câu hỏi thử thách tư duy, dự đoán hành vi của cụm node khi xuất hiện phân mảnh mạng hoặc khi một node bất ngờ khởi động lại.
- **Thực hành kiểm chứng qua demo kit** — Bạn sử dụng tài liệu kịch bản đi kèm để agent dựng môi trường thử nghiệm trên Docker, tái hiện lỗi trên staging và đối chiếu số đo trước sau khi tối ưu.

## Khóa học dành cho ai

1. **Developer xây dựng app cùng AI agent** — Bạn có app chạy trên Postgres, bắt đầu bổ sung read replica hoặc mở rộng nhiều dịch vụ, và cần hiểu rõ bản chất dữ liệu để kiểm soát các đoạn code kiến trúc do agent sinh ra.
2. **Kỹ sư chuẩn bị cấu hình failover tự động** — Bạn cần bộ tiêu chí rõ ràng để lựa chọn node thay thế, kiểm soát thời gian dừng ghi và thiết lập lớp rào chắn ngăn ngừa split brain trước khi đưa vào production.
3. **Kỹ sư vận hành hệ thống dữ liệu tại nhiều chi nhánh** — Bạn đang đối mặt với bài toán đồng bộ dữ liệu giữa các kho hàng hoặc data center ngoại tuyến, và cần các giải pháp xử lý conflict an toàn như version vector hay phân bổ hạn mức trước.

## Những điều cần lưu ý

- **Yêu cầu nền tảng thực tế** — Khóa học không đòi hỏi bạn phải là quản trị viên database chuyên nghiệp, chỉ cần bạn đã từng làm việc với Postgres ở mức cơ bản, hiểu khái niệm transaction và đọc hiểu TypeScript cùng SQL; đổi lại, bạn sẽ nắm vững nguyên lý vận hành của dữ liệu phân tán từ góc nhìn của một kỹ sư app.
- **Khóa học bổ trợ liên quan** — Ba bài học nền tảng về timeline concurrency, read replica và lease được trích xuất từ chuỗi chương trình System Design của 200Lab; nếu cần củng cố sâu hơn về source of truth hay outbox pattern, bạn có thể tham khảo thêm các khóa học chuyên đề này để hoàn thiện bức tranh tổng thể.
- **Tập trung vào bản chất thay vì cấu hình công cụ** — Khóa học không liệt kê chi tiết mọi tham số cấu hình của các phần mềm quản trị cụ thể hay đi sâu vào kỹ thuật sharding phức tạp; đổi lại, bạn có được tư duy kiến trúc độc lập để tự tin đánh giá và chỉ đạo agent thiết lập bất kỳ công cụ failover nào.
- **Ý nghĩa của số liệu thực nghiệm** — Toàn bộ các mốc thời gian, số lượng đơn hàng và chỉ số lag trong bài giảng được xây dựng nhằm phục vụ việc phân tích bản chất kỹ thuật; đổi lại, bạn sẽ có các công thức và quy trình đo đạc chuẩn mực để áp dụng trực tiếp vào hệ sinh thái của chính mình.

## Bắt đầu từ đâu

Khóa học mở đầu bằng câu hỏi nền tảng: khi một hệ thống lưu trữ nhiều bản sao thì bản ghi nào thực sự đáng tin cậy. Bạn sẽ quan sát năm sự cố điển hình của một app đang mở rộng quy mô và theo dõi buổi failover drill thực tế (chủ động tắt primary trên staging để đo) kéo dài 41 phút dù thao tác promote chỉ mất 3 phút. Việc phân tích 38 phút chờ đợi vô ích đó sẽ chỉ ra ba số liệu cốt lõi bạn cần nắm giữ trước khi quyết định nâng cấp hệ thống lên nấc tiếp theo.

## Chương trình

- Dữ liệu nằm trên nhiều máy thì bản nào đáng tin (miễn phí)

### Node lỗi, network partition và đồng hồ của các máy lệch nhau

- Health-check báo replica chết trong khi replica vẫn chạy (miễn phí)
- Đọc timeline của hai request chạy song song để tìm race condition (miễn phí)
- Màn hình lịch sử đơn hiện bước hoàn tiền trước bước hủy (miễn phí) · quiz

### Replication lag và consistency khi đọc từ replica

- Read replica gánh bớt tải đọc cho database primary · quiz
- Replication lag tăng vọt mỗi đêm khi job batch chạy · quiz
- Mọi lệnh ghi bị treo khi replica đồng bộ khởi động lại · quiz
- Đã đăng xuất khỏi mọi thiết bị mà request cũ vẫn được chấp nhận · quiz
- Số đơn hôm nay giảm đi khi người bán tải lại trang · quiz
- Tình huống: đơn vừa đặt không hiện trong lịch sử đơn · kit cho agent

### Chọn primary mới mà không để xảy ra split brain

- Lease đã hết hạn mà worker cũ vẫn ghi dữ liệu · quiz
- Script watchdog tự promote replica khi primary vẫn đang chạy · quiz
- Primary cũ vẫn nhận lệnh ghi sau khi replica đã được promote

### Failover, failback và sửa dữ liệu bị ghi sai

- Primary chết thì nên promote replica nào · quiz
- Đưa primary cũ trở lại cụm mà không ghi đè dữ liệu mới · quiz
- Sửa dữ liệu bị ghi sai mà không đưa cả database về quá khứ · quiz
- Tình huống: khởi động lại nhầm primary cũ tạo ra hai primary · kit cho agent

### Nhiều node cùng nhận lệnh ghi thì xử lý conflict thế nào

- Chia dữ liệu theo nơi ghi trước khi bật multi-leader
- Giỏ hàng hiện lại món đã xóa sau khi một node khởi động lại · quiz
- Last-write-wins âm thầm ghi đè bản sửa địa chỉ giao hàng · quiz
- Mã giảm giá vượt giới hạn dù counter CRDT không đếm sót lượt nào · quiz
- Tình huống: tồn kho sai sau khi hai kho đồng bộ lại dữ liệu · kit cho agent
