0

"Nghe" Database thay vì "Hỏi": Tại sao CDC là cứu cánh khi Event Sourcing quá xa vời?

Chào anh em, lại là câu chuyện "làm sao để đồng bộ dữ liệu" đây.

Trong sự nghiệp làm Backend hay Kiến trúc sư dữ liệu, chắc hẳn ít nhất một lần anh em đã đau đầu với bài toán: “Làm sao để khi User cập nhật thông tin ở DB chính, thì Search Index (Elasticsearch), Cache (Redis) hay Report DB cũng phải nhảy số ngay lập tức?

Nhiều người sẽ nghĩ ngay đến Event Sourcing (ES) – nghe rất "cool ngầu", chuẩn kiến trúc phân tán. Nhưng tin mình đi, nếu hệ thống của bạn chưa đủ tầm cỡ hoặc team chưa đủ "đô", ES sẽ là một cơn ác mộng về vận hành.

Hôm nay mình muốn chia sẻ về một hướng đi "nhẹ đầu" hơn nhưng cực kỳ mạnh mẽ: Change Data Capture (CDC). Hay mình vẫn hay gọi vui là: Thay vì bắt App phải la hét (bắn Event), hãy học cách lắng nghe hơi thở của Database.

1. Event Sourcing vs CDC: Khi lý thuyết va chạm thực tế

Về cơ bản, cả hai đều giúp chúng ta theo dõi lịch sử thay đổi dữ liệu. Nhưng cách tiếp cận thì khác một trời một vực:

Event Sourcing: Bạn lưu trữ "hành động". Muốn biết số dư hiện tại? Bạn phải cộng dồn tất cả các giao dịch từ quá khứ.

Nỗi đau: Rebuild lại State cực kỳ phức tạp nếu logic nghiệp vụ thay đổi theo thời gian (Versioning). Snapshotting cũng là một bài toán khó nhằn.

Change Data Capture (CDC): Bạn "rình" ở tầng Database. Bất kỳ một lệnh INSERT, UPDATE, DELETE nào làm thay đổi dữ liệu, CDC sẽ tóm lấy và đẩy đi.

Điểm cộng: Bạn không cần sửa một dòng code Logic nào. Database làm gì, CDC biết cái đó. Đặc biệt, khi cần rebuild lại lịch sử để sync sang một DB mới, CDC (qua cơ chế đọc Log) ít gây lag hệ thống hơn nhiều.

Kinh nghiệm xương máu: Nếu bạn muốn có Audit Trail mà không muốn đập đi xây lại toàn bộ code Base, hãy chọn CDC.

2. Case thực tế: Khi "Double Write" phản bội bạn

Hồi trước, team mình dùng cách thủ công: Trong code, sau khi db.Save(user), mình sẽ gọi thêm elastic.Index(user).

Kết quả? DB lưu thành công nhưng mạng lag, ElasticSearch chết đứng, dữ liệu hai bên lệch nhau thê thảm. Việc viết code để handle retry, bù trừ dữ liệu lúc này còn khổ hơn là viết tính năng mới.

Đó là lúc Debezium + Kafka xuất hiện như một vị cứu tinh.

Tại sao lại là bộ đôi này?

Debezium: Nó đóng vai trò như một "gián điệp" đọc trực tiếp binlog (MySQL) hoặc WAL (Postgres). Nó không query vào bảng, nên không làm chậm DB của bạn.

Kafka: Làm cái phễu điều hòa dòng chảy dữ liệu. DB có nổ 1000 record/s thì Kafka vẫn bình tĩnh giữ đó cho các bên khác (Consumer) tiêu thụ từ từ.

3. Demo Pipeline: Từ file CSV thô đến Elasticsearch "real-time"

Hãy tưởng tượng bạn có một file CSV chứa hàng triệu sản phẩm cần import. Nếu chơi kiểu truyền thống, ElasticSearch của bạn dễ "ngáp" lắm. Đây là cách mình triển khai:

  1. CSV → DB: Một tool nhỏ đẩy dữ liệu vào MySQL/Postgres.
  2. DB → Debezium: Debezium thấy binlog nhảy, lập tức "capture" sự kiện.
  3. Debezium → Kafka: Sự kiện được đóng gói thành JSON đẩy vào Topic.
  4. Kafka → Elasticsearch: Một Consumer (hoặc Kafka Connect) nghe Topic đó và update vào Search Index.

Sequence Diagram cho anh em dễ hình dung:

sequenceDiagram
    participant User as User/Script
    participant DB as Main Database (Source)
    participant Deb as Debezium (CDC)
    participant K as Kafka Topic
    participant ES as Elasticsearch (Sink)

    User->>DB: Import CSV / Update Data
    Note over DB: Ghi vào Table & Log (Binlog/WAL)
    
    Deb->>DB: Đọc Log âm thầm
    Deb->>K: Emit "Change Event" (JSON)
    
    K->>ES: Consumer đồng bộ dữ liệu
    Note right of ES: Search Index luôn khớp với DB

4. Những kịch bản "cứu mạng" nhờ CDC

  • Rebuild Search Index: Bạn muốn thay đổi Analyzer trong Elasticsearch? Chỉ cần cho Debezium đọc lại Log từ đầu (Snapshot), toàn bộ dữ liệu sẽ được đẩy sang ES mới mà không cần chạm vào Code Backend.
  • Audit Log: Ai đã sửa cái gì, lúc nào? CDC lưu lại toàn bộ before và after của mỗi dòng dữ liệu. Đây là bằng chứng thép cho các hệ thống tài chính.
  • Rollback dữ liệu: Nếu lỡ tay chạy một lệnh UPDATE nhầm, bạn có thể dựa vào Stream sự kiện trong Kafka để tìm lại trạng thái cũ của dữ liệu nhanh chóng.

5. Kết luận: Nên chọn cái nào?

Đừng cuồng tín công nghệ.

Dùng Event Sourcing nếu hệ thống của bạn thực sự cần "Event-driven" từ lõi (như các hệ thống ngân hàng core, trading).

Dùng CDC nếu bạn muốn: Hệ thống ổn định, code sạch sẽ, khả năng mở rộng cao và quan trọng nhất là ngủ ngon mỗi đêm khi phải sync dữ liệu giữa các Service.

Anh em đã từng "ăn hành" với việc đồng bộ dữ liệu chưa? Cùng chia sẻ dưới comment nhé!

P/S: Ở bài sau, mình sẽ hướng dẫn chi tiết cách cấu hình Debezium Connector để không làm "sập" con DB Production của bạn. Stay tuned!


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.