CRDT là gì? Cấu trúc dữ liệu hội tụ không xung đột

CRDT là gì? Kiểu dữ liệu hội tụ không xung đột

Conflict-free Replicated Data Type (CRDT) là cấu trúc dữ liệu được thiết kế để sao chép trên nhiều nút trong hệ thống phân tán, cho phép mỗi nút cập nhật độc lập mà không cần phối hợp trực tiếp, đồng thời đảm bảo các bản sao cuối cùng luôn hội tụ về cùng một trạng thái. Đây là cách giải quyết bài toán nhất quán dữ liệu cho ứng dụng offline-first và hệ thống phân tán nhiều người dùng.

Sơ đồ CRDT dựa trên trạng thái, hai bản sao độc lập hợp nhất về cùng một giá trị chung

Hai hướng tiếp cận chính: State-based và Operation-based

CRDT được phân thành hai lớp tùy thuộc vào cách truyền tải thay đổi giữa các nút:

  • State-based CRDT (CvRDT): mỗi nút gửi toàn bộ trạng thái hiện tại cho các nút khác. Hàm merge (join) kết hợp hai trạng thái bằng phép hợp nhất trên một semi-lattice. Cách này đơn giản, luôn hội tụ, nhưng tốn băng thông khi trạng thái lớn.
  • Operation-based CRDT (CmRDT): chỉ gửi các phép toán đã áp dụng. Các phép toán phải thỏa mãn ba tính chất: giao hoán (commutative), liên kết (associative) và lũy lặp an toàn (idempotent). Hiệu quả hơn về băng thông nhưng cần bảo đảm thứ tự nhân quả khi truyền tin.

Sơ đồ CRDT dựa trên phép toán, các thay đổi được gửi và hợp nhất theo thứ tự tới mọi bản sao

Các loại CRDT phổ biến

Loại CRDT Ứng dụng điển hình
G-Counter (Grow-only Counter) Đếm lượt xem, số lần ghi log chỉ tăng
PN-Counter (Positive-Negative Counter) Điểm Like/Dislike, điểm số có thể tăng lẫn giảm
LWW-Register (Last-Writer-Wins Register) Giá trị cấu hình, timestamp cuối cùng thắng
OR-Set (Observed-Remove Set) Danh sách thẻ tag, tập người được gán quyền
RGA và YATA (sequence CRDT) Biên tập cộng tác văn bản nhiều người dùng

Ứng dụng thực tế

CRDT là xương sống của nhiều sản phẩm quen thuộc mà bạn dùng hằng ngày:

  • Trình soạn thảo cộng tác: Figma, Google Docs, Apple Notes, các editor kiểu Atom/VS Code dùng CRDT để hợp nhất thay đổi văn bản.
  • Cơ sở dữ liệu phân tán: Riak hỗ trợ CRDT ở tầng ứng dụng, Redis và CockroachDB có các kiểu dữ liệu tương tự với cơ chế hợp nhất.
  • Ứng dụng phi tập trung: ví offline, trình ghi chú làm việc không mạng rồi đồng bộ sau.
  • Edge và IoT: các cảm biến báo cáo trạng thái theo lô mà không cần giữ kết nối thường trực với trung tâm.

So sánh với consensus truyền thống

Raft và Paxos đảm bảo nhất quán mạnh (strong consistency) bằng đồng thuận của đa số các bản sao. CRDT đi theo hướng khác: chỉ cần tính chất hội tụ và hàm merge có tính giao hoán, liên kết, lũy lặp.

Tiêu chí CRDT Raft/Paxos
Nhất quán Eventual (hội tụ) Strong (tức thời)
Phối hợp Không cần, hoạt động offline Cần leader và quorum
Độ trễ ghi Thấp, ghi tại chỗ Cao hơn, chờ commit
Dữ liệu phải hội tụ Cấu trúc bán duy trì (monotonic) Mọi cấu trúc dữ liệu

Khi nào nên chọn CRDT

Hãy chọn CRDT khi ứng dụng cần làm việc khi mất mạng, nhiều thiết bị cùng chỉnh sửa dữ liệu, và muốn tránh độ phức tạp vận hành của consensus. Đổi lại, bạn phải chấp nhận eventual consistency: người dùng có thể tạm thời thấy trạng thái cũ ở một số nút, và metadata tăng trưởng theo số lần hợp nhất. Nếu dữ liệu là tiền, hạn chế tín dụng hoặc giao dịch tài chính nơi sai số là không chấp nhận được, hãy giữ Raft hoặc cơ sở dữ liệu quan hệ có transaction.

Xử lý xung đột và thiết kế CRDT hiệu quả

Viết CRDT đúng đòi hỏi hiểu rõ ngữ nghĩa dữ liệu. Một bài học đắt giá là các kiểu dữ liệu không tự nhiên hội tụ (như map cần làm theo LWW-Element-Set hoặc OR-Set) dễ gây hành vi phi mong muốn. Các thư viện như Yjs và Automerge đã đóng gói các kiểu CRDT phổ biến, giúp lập trình viên tập trung vào logic ứng dụng thay vì toán học hội tụ. Khi mở rộng, nên dùng delta-CRDT để chỉ gửi phần thay đổi thay vì toàn bộ trạng thái, giảm băng thông đáng kể. Một lời khuyên thực tế nữa là luôn ghi kèm vector đồng hồ (vector clock) để phát hiện xung đột ngay cả khi bạn chọn chiến lược last-writer-wins, từ đó tránh được trường hợp hai người cùng sửa một trường mà người sau ghi đè mất thay đổi của người trước.

Tóm tắt

CRDT đánh đổi tính nhất quán tức thời lấy khả năng chịu lỗi và độ trễ thấp. Với các ứng dụng cộng tác và offline-first, đây là lựa chọn kiến trúc hợp lý nhất.

Nguồn tham khảo: Conflict-free replicated data type trên Wikipedia, A comprehensive study of Conflict-free Replicated Data Types của Shapiro và cộng sự, và thư viện mã nguồn mở Yjs.

Tôi là một lập trình viên IOS. Code chính là IOS nhưng thỉnnh thoảng vẫn đá sang Android hoặc web. Mặc dù không quá thông thạo nhưng tôi sẽ chia sẻ những kiến thức mà mình đã tìm hiểu, áp dụng qua.

Bài viết liên quan

D-Bus là gì? Kiến trúc giao tiếp giữa các tiến trình trên Linux

D-Bus là gì? Kiến trúc giao tiếp giữa các tiến trình trên Linux D-Bus là gì? D-Bus là hệ thống giao tiếp giữa các tiến trình (IPC) phổ biến nhất…

Xem thêm

OpenGL là gì? Kiến trúc đồ họa và pipeline dựng hình trên GPU

OpenGL là gì? Kiến trúc đồ họa và pipeline dựng hình OpenGL (Open Graphics Library) là chuẩn API đa nền tảng để vẽ đồ họa hai chiều và ba chiều,…

Xem thêm

Huffman coding là gì? Thuật toán nén dữ liệu theo tần suất ký tự

Huffman coding là gì? Thuật toán nén dữ liệu theo tần suất ký tự Sơ đồ cây Huffman dựng từ tần suất bốn ký tự, mỗi lá là một ký…

Xem thêm
0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest
0 Comments
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất