Case study — etcd/ZooKeeper (consensus) vs Cassandra (quorum)
Ghép cả track: etcd/ZooKeeper dùng consensus cho nhất quán mạnh (khoá, config, bầu leader); Cassandra dùng quorum cho khả dụng cao. Chọn theo nhu cầu.
TL;DR: Hai họ hệ phân tán hiện thân cho hai đầu đánh đổi CAP. etcd/ZooKeeper là consensus service (Raft/ZAB): thiên CP, ghi linearizable trên dữ liệu nhỏ (metadata) — dùng cho khoá phân tán, config, service discovery, bầu leader; đổi lại throughput thấp và mất khả dụng khi mất đa số. Cassandra là wide-column store leaderless, quorum tunable (w + r > n): thiên AP, khả dụng cao + ghi nhanh trên dữ liệu lớn — đổi lại chỉ eventual/tunable consistency, phải hoà giải xung đột. Chọn theo nhu cầu: dữ liệu điều phối cần một sự thật tuyệt đối, nhỏ → consensus store; dữ liệu nghiệp vụ lớn, chịu trễ, cần luôn ghi được → quorum store. Kiến trúc thật thường dùng cả hai.
Đây là bài khép course. Năm module trước cho bạn từng mảnh: cách đo hệ, replication, partitioning, transaction phân tán, và những rắc rối của hệ phân tán; module này cho ngôn ngữ về nhất quán (linearizability, causal), CAP, và consensus. Giờ ta ghép tất cả vào hai hệ thật mà bạn sẽ gặp trong mọi kiến trúc lớn — và quan trọng hơn, luyện tự quyết dùng cái nào cho một nhu cầu cụ thể.
Vì đây là bài độc lập (bạn đã có đủ khung), phần chính không phải giảng lại lý thuyết mà là tự chọn hệ + biện minh cho vài tình huống; đáp án mẫu nằm trong <SelfCheck> để bạn đối chiếu sau khi đã tự quyết.
1. Analogy — két sắt ngân hàng vs cửa hàng tiện lợi 24/7
Két sắt trung tâm (consensus store): một chỗ duy nhất giữ những thứ phải tuyệt đối đúng — sổ chủ quyền, chìa khoá. Muốn lấy phải qua thủ tục xác nhận nhiều bên (đa số ký). Chậm, và nếu đủ nhân sự chủ chốt vắng thì đóng cửa — nhưng không bao giờ có hai "sổ chủ quyền" mâu thuẫn.
Cửa hàng tiện lợi 24/7 khắp phố (quorum store): luôn mở, phục vụ nhanh, ở đâu cũng có. Hai chi nhánh có thể lệch tồn kho vài phút rồi khớp lại sau. Không dùng nó để giữ sổ chủ quyền — nhưng để bán hàng khối lượng lớn thì tuyệt.
| Đời thường | Hệ phân tán |
|---|---|
| Két sắt trung tâm, đa số ký mới mở | Consensus store (etcd/ZooKeeper) — CP, linearizable |
| Vắng người chủ chốt → đóng cửa | Mất đa số → mất khả dụng |
| Cửa hàng 24/7 luôn mở khắp nơi | Quorum store (Cassandra) — AP, luôn ghi được |
| Tồn kho lệch vài phút rồi khớp | Eventual consistency, hoà giải sau |
Consensus store = "két sắt": ít đồ, cực đúng, đóng cửa khi thiếu người. Quorum store = "cửa hàng 24/7": nhiều đồ, luôn mở, chấp nhận lệch tạm. Đừng cất sổ chủ quyền ở cửa hàng tiện lợi.
2. etcd / ZooKeeper — consensus store (CP)
etcd (dùng Raft, bài 04) và ZooKeeper (dùng ZAB — một giao thức họ hàng) là các coordination service: kho key-value nhỏ, với ghi luôn linearizable (đi qua consensus). Đọc thì khác nhau giữa hai hệ: ZooKeeper mặc định đọc từ bản cục bộ của node nhận request — nhanh nhưng có thể cũ (không linearizable), phải gọi sync() trước đọc mới đảm bảo linearizable; etcd (v3) đọc linearizable mặc định (qua ReadIndex, xác nhận với leader trước khi trả lời). Chúng không thiết kế để chứa terabyte dữ liệu nghiệp vụ; chúng chứa metadata điều phối cần đúng tuyệt đối:
- Khoá phân tán / lease: đúng một client giữ khoá tại một thời điểm (cần recency của bài 01).
- Bầu leader: cụm ứng dụng của bạn (ví dụ nhiều instance của một scheduler) bầu một instance dẫn dắt — đẩy bài toán consensus xuống cho etcd lo.
- Config động + service discovery: ai đang sống, endpoint ở đâu — mọi node đọc cùng một sự thật.
- Watch: client theo dõi một key và được báo khi đổi — nền cho phối hợp phản ứng.
Vì mọi ghi đi qua consensus (đạt đa số mới commit), etcd/ZooKeeper thiên CP: khi mất đa số (quá f node chết, hoặc phía thiểu số của partition), chúng từ chối phục vụ ghi thay vì trả lời có thể sai. Throughput vì thế thấp hơn hẳn một quorum store — đó là cái giá của "két sắt".
3. Cassandra — leaderless quorum store (AP)
Cassandra (lấy cảm hứng từ Amazon Dynamo) là wide-column store, leaderless: không có node đặc biệt nào; client ghi/đọc qua quorum tunable trên các replica. Bạn vặn hai núm W (số replica xác nhận khi ghi) và R (số replica đọc), trên N bản sao:
- Đặt
W + R > N→ tập ghi và tập đọc giao nhau → đọc thường thấy ghi mới nhất (nhất quán mạnh hơn, nhưng vẫn không phải linearizable do lệch định thời — bài 01 mục 6). - Đặt
W + R ≤ N(ví dụW=1) → ghi cực nhanh, luôn nhận được, nhưng eventual — đọc có thể thấy cũ.
Cassandra thiên AP: khi partition, các phía vẫn nhận ghi (với sloppy quorum / hinted handoff), rồi hoà giải xung đột sau bằng last-write-wins theo timestamp — thừa kế đúng rủi ro mất ghi âm thầm của LWW đã học ở Module 5 — Đồng hồ không tin cậy (ghi mới hơn theo thời gian thật nhưng mang timestamp nhỏ hơn do clock skew sẽ bị vứt). Nó tối ưu cho ghi khối lượng lớn, khả dụng cao, đa vùng — dữ liệu nghiệp vụ như event log, time-series, feed. Không dùng nó cho khoá phân tán ở chế độ quorum mặc định: thiếu recency chặt nên hai client có thể cùng tưởng mình giữ khoá (Cassandra có Lightweight Transactions dùng Paxos cho thao tác linearizable, nhưng đắt và hiếm dùng vì lệch khỏi mô hình leaderless).
4. Chọn hệ nào cho nhu cầu nào?
| Tiêu chí | etcd / ZooKeeper (CP) | Cassandra (AP) |
|---|---|---|
| Nền tảng | Consensus (Raft / ZAB) | Leaderless quorum (Dynamo-style) |
| Nhất quán | Ghi linearizable; đọc: ZooKeeper mặc định có thể cũ (cần sync()), etcd mặc định linearizable | Eventual → tunable (W+R>N) |
| Khi partition | Từ chối ở phía thiểu số (mất A) | Vẫn phục vụ (mất C, hoà giải sau) |
| Khối lượng dữ liệu | Nhỏ (metadata) | Lớn (nghiệp vụ) |
| Throughput ghi | Thấp (qua consensus) | Cao |
| Use case điển hình | Khoá, config, bầu leader, discovery | Event log, time-series, feed, catalog lớn |
flowchart TD
Q{"Du lieu nay can gi?"}
Q -->|"Mot su that dung tuyet doi<br/>+ it du lieu (dieu phoi)"| CP["Consensus store<br/>etcd / ZooKeeper"]
Q -->|"Luon ghi duoc + nhieu du lieu<br/>+ chiu duoc tre"| AP["Quorum store<br/>Cassandra"]
CP --> BOTH["Kien truc thuc te:<br/>dung CA HAI"]
AP --> BOTHỞ track thuật toán bạn đã bổ đôi cơ chế bên trong: Cassandra dùng consistent hashing + quorum + gossip; etcd dùng Raft. Bài này nhìn ở tầng kiến trúc chọn hệ: cùng một cặp hệ, nhưng câu hỏi giờ là "dữ liệu của tôi thuộc két sắt hay cửa hàng 24/7?" — quyết định dựa trên đảm bảo nhất quán và mức khả dụng cần, không phải nội tạng thuật toán.
5. Tự quyết — đến lượt bạn
Bạn đã có đủ khung để chọn. Với mỗi tình huống dưới, tự quyết consensus store (etcd/ZooKeeper) hay quorum store (Cassandra) và tự viết ra lý do (đảm bảo cần gì, chịu được gì) trước khi mở đáp án mẫu.
(A) Khoá phân tán cho job scheduler. Nhiều instance của một scheduler cùng chạy; chỉ đúng một instance được thực thi mỗi job (chạy hai lần = tính tiền hai lần). Cần một khoá "ai đang chạy job X".
(B) Lưu event click của người dùng. Hàng trăm nghìn event/giây, đa vùng; mất vài event lẻ hoặc thấy trễ vài giây thì chấp nhận được; không bao giờ được từ chối ghi vì "đang phân tích".
(C) Bảng cấu hình feature flag mà mọi service đọc; khi bật/tắt một flag, cả hệ phải thấy cùng một trạng thái gần như tức thì, không được "nửa hệ bật nửa hệ tắt".
(D) Catalog sản phẩm của một sàn thương mại điện tử lớn: rất nhiều bản ghi, đọc nặng, cần luôn phục vụ kể cả khi một vùng mất kết nối; giá/hàng lệch vài giây thì chấp nhận.
Tự trả lời (a) chọn hệ nào, (b) đảm bảo quyết định (linearizable hay eventual đủ?), (c) nếu chọn sai thì hỏng thế nào — rồi mới mở đáp án.
Q1Tình huống (A) khoá phân tán cho scheduler: chọn consensus store hay quorum store? Vì sao, và nếu chọn nhầm thì hỏng thế nào?▸
Consensus store (etcd/ZooKeeper). Khoá cần linearizability — một sự thật mới nhất duy nhất về "ai đang giữ khoá job X". etcd cung cấp lease + khoá linearizable đúng cho việc này; đây là use case kinh điển của coordination service.
Chọn nhầm Cassandra sẽ hỏng: quorum store thiếu recency chặt (bài 01 mục 6) — hai instance đọc hai replica lệch nhau có thể cùng thấy khoá "trống" và cùng chạy job → thực thi hai lần, tính tiền hai lần. Đúng loại lỗi mà chỉ nhất quán mạnh (consensus) mới chặn được.
Q2Tình huống (B) lưu event click khối lượng lớn: chọn hệ nào? Đảm bảo nào là đủ, và vì sao consensus store là lựa chọn tệ ở đây?▸
Quorum store (Cassandra). Eventual consistency là đủ: mất vài event lẻ hoặc thấy trễ vài giây không sai nghiệp vụ, nhưng yêu cầu "không bao giờ từ chối ghi" đòi khả dụng cao — đúng thế mạnh AP + ghi nhanh của Cassandra trên dữ liệu lớn, đa vùng.
Consensus store tệ ở đây vì: (1) throughput thấp — mỗi ghi qua đa số, không kham nổi hàng trăm nghìn event/giây; (2) nó từ chối ghi khi mất đa số, vi phạm thẳng yêu cầu "không bao giờ từ chối"; (3) nó thiết kế cho ít metadata, không phải kho dữ liệu lớn. Dùng "két sắt" để chứa luồng event là sai công cụ.
Q3Tình huống (C) feature flag toàn hệ: chọn hệ nào, và đảm bảo nào là mấu chốt? So sánh ngắn với tình huống (B) để làm rõ vì sao khác nhau.▸
Consensus store (etcd/ZooKeeper). Mấu chốt là "không nửa hệ bật nửa hệ tắt" — cần mọi service thấy cùng một trạng thái flag gần như tức thì, tức linearizable + watch để đẩy thay đổi. etcd/ZooKeeper làm đúng việc này (config động + watch).
Khác (B) ở khối lượng và yêu cầu nhất quán: feature flag là ít dữ liệu nhưng cần một sự thật đồng nhất (giống "sổ chủ quyền"); event click là nhiều dữ liệu chịu được lệch tạm (giống "hàng bán ở cửa hàng 24/7"). Cùng là "ghi rồi đọc", nhưng một bên trả giá cho nhất quán, bên kia trả giá cho khả dụng + throughput — nên chọn ngược đầu CAP.
Q4Tình huống (D) catalog sản phẩm sàn TMĐT lớn: chọn hệ nào? Vì sao "luôn phục vụ kể cả khi một vùng mất kết nối" đẩy quyết định về một phía CAP cụ thể?▸
Quorum store (Cassandra). Catalog là nhiều bản ghi, đọc nặng, đa vùng, và giá/hàng lệch vài giây thì chấp nhận — hợp với AP + khả năng mở rộng ngang của Cassandra.
Yêu cầu "luôn phục vụ kể cả khi một vùng mất kết nối" chính là chọn A khi partition (bài 03): khi một vùng bị cắt, ta muốn nó vẫn trả kết quả (có thể hơi cũ) chứ không đóng cửa. Đó là hành vi AP. Một consensus store CP sẽ làm ngược lại — phía thiểu số từ chối phục vụ để giữ nhất quán, mâu thuẫn với yêu cầu khả dụng của catalog.
Q5Vì sao nhiều kiến trúc thực tế dùng cả hai loại hệ cùng lúc thay vì chọn một? Cho một ví dụ phối hợp cụ thể.▸
Vì một hệ lớn có hai loại dữ liệu khác bản chất: dữ liệu nghiệp vụ khối lượng lớn (cần khả dụng + throughput) và metadata điều phối nhỏ nhưng cần đúng tuyệt đối (cần nhất quán mạnh). Không hệ nào tối ưu cả hai — ép một loại vào hệ sai gây hoặc bug nhất quán, hoặc nghẽn throughput.
Ví dụ phối hợp: một cụm lưu dữ liệu người dùng trên Cassandra (AP, ghi lớn), nhưng chính cụm ứng dụng đó dùng etcd/ZooKeeper để bầu leader (ai điều phối rebalance), giữ khoá cho tác vụ chạy-một-lần, và phát config đồng nhất. Quorum store giữ "hàng hoá", consensus store giữ "chìa khoá và sổ sách" — mỗi thứ đặt đúng két.
6. 📚 Đào sâu — nguồn gốc & tài liệu
- Designing Data-Intensive Applications (Kleppmann) — Chương 9, mục "Membership and Coordination Services" — vì sao ZooKeeper/etcd chứa ít dữ liệu nhưng linearizable, và chúng lo bầu leader / khoá / service discovery cho hệ khác.
- etcd Documentation — "Why etcd" — etcd dùng Raft, thiên nhất quán mạnh, dành cho metadata quan trọng (Kubernetes dùng etcd làm kho trạng thái).
- DeCandia et al. (2007), "Dynamo: Amazon's Highly Available Key-value Store" (SOSP) — paper nền của Cassandra: leaderless, quorum tunable, hinted handoff, đổi nhất quán mạnh lấy "always writeable".
- Apache Cassandra — Architecture / Tunable Consistency — cách vặn
W/Rđể trượt giữa eventual và nhất quán mạnh hơn.
Ghi chú: Kubernetes là ví dụ sống: etcd giữ toàn bộ trạng thái cluster (nhất quán mạnh, ít dữ liệu), còn dữ liệu ứng dụng chạy trên các store khác. Đúng mô hình "consensus store cho điều phối, store khác cho dữ liệu".
7. Liên hệ các bài khác
- Bài 01 — Linearizability: là đảm bảo etcd/ZooKeeper cung cấp và Cassandra (mặc định) không — gốc của việc khoá phải đặt ở consensus store.
- Bài 03 — CAP: etcd/ZooKeeper (CP) vs Cassandra (AP) là hai hiện thân trực tiếp của lựa chọn C-vs-A khi partition.
- Bài 04 — Consensus/Raft: etcd đóng gói Raft thành khoá/config/bầu leader dùng được ngay — bài này là "Raft ở tầng sản phẩm".
- Module 2 — Leaderless replication: quorum
w + r > ncủa Cassandra được mổ cơ chế ở đó. - Module 5 — Fencing token: khi dùng khoá từ etcd/ZooKeeper, fencing token chống client "giữ khoá cũ" tỉnh lại — ghép với nhất quán mạnh để failover an toàn.
8. Tóm tắt
- etcd / ZooKeeper = consensus store (Raft/ZAB), CP, linearizable trên metadata nhỏ — khoá, config, bầu leader, service discovery; mất đa số → từ chối phục vụ.
- Cassandra = leaderless quorum tunable (
W+R>N), AP, khả dụng cao + ghi nhanh trên dữ liệu lớn; đổi lại eventual/tunable consistency, hoà giải xung đột. - Chọn: một sự thật đúng tuyệt đối trên ít dữ liệu điều phối → consensus store; luôn ghi được trên nhiều dữ liệu, chịu trễ → quorum store.
- Chọn nhầm: khoá trên quorum store → chạy trùng (thiếu recency); event log trên consensus store → nghẽn + bị từ chối ghi.
- Kiến trúc thật thường dùng cả hai: quorum store giữ dữ liệu, consensus store giữ khoá + bầu leader (ví dụ Kubernetes + etcd).
- Đây là nơi cả track hội tụ: đảm bảo nhất quán (bài 01-02) + CAP (bài 03) + consensus (bài 04) quyết định chọn hệ nào cho dữ liệu nào.
Bài tiếp theo: Module 6 — Tổng kết & cheat sheet
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