Đã bao thập kỷ rồi, cứ nhắc đến tự động hóa theo lịch trình trong các hệ thống backend là cron job
mặc định được chọn: cứ chạy mỗi giờ, mỗi ngày, mỗi 15 phút. Nhưng gần đây, có một cách mới tốt hơn, nhanh hơn và đáng tin cậy hơn trong khá nhiều trường hợp.
Change Data Capture (CDC)
đang cách mạng hóa cách các hệ thống hiện đại phản ứng với những thay đổi dữ liệu, nó thay thế mấy cái cron job
dễ gãy bằng các quy trình làm việc dựa trên sự kiện, diễn ra trong thời gian thực.
Đây là lý do tại sao cron
có thể bị CDC
thay thế.

Cron Jobs: Dấu Vết Của Thời Đại Polling
Cron
thì đơn giản thật. Nhưng mà đơn giản quá.
Một cron job
điển hình trong hệ thống backend dùng Spring Boot hoặc Go có thể trông như thế này:
@Scheduled(cron = "0 */5 * * * *") // every 5 minutes
public void syncOrders() {
List newOrders = orderRepository.findUnprocessed();
for (Order order : newOrders) {
process(order);
}
}
Hoặc trong Go:
ticker := time.NewTicker(5 * time.Minute)
for range ticker.C {
orders := db.FindUnprocessedOrders()
for _, o := range orders {
process(o)
}
}
Cái này thì chạy được đó. Nhưng nó có những hạn chế nghiêm trọng:
- Độ trễ: Bạn phải chờ vài phút để phát hiện ra thay đổi.
- Dư thừa: Mỗi lần chạy là quét toàn bộ dữ liệu, tốn tài nguyên.
- Đau đầu với đồng thời: Hai
cron job
có thể xung đột nếu một cái bị chậm. - Tốn công vận hành: Giám sát, thử lại, lên lịch lại, tất cả đều làm tăng độ phức tạp.
Kết quả là gì? Hệ thống trên lý thuyết thì phản ứng nhanh, nhưng thực tế thì lại ì ạch và ngốn tài nguyên.
Change Data Capture là gì?
CDC
là một mô hình mà hệ thống của bạn sẽ lắng nghe các thay đổi trong database ngay lập tức, không cần phải kiểm tra định kỳ. Thay vì phải hỏi “có gì thay đổi không?”, database sẽ “kể” cho bạn biết cái gì đã thay đổi.
Các công cụ phổ biến:
Debezium
(dùng cho PostgreSQL, MySQL, MongoDB, vân vân)Kafka Connect
(để truyền các thay đổi vào Kafka thành luồng dữ liệu)Litestream
,Maxwell
,AWS DMS
, và nhiều công cụ khác
Thay thế Cron bằng CDC
Cron
: Kiểm tra và xử lý mỗi 5 phút.
// Every 5 mins
rows := db.Query("SELECT * FROM orders WHERE status = 'new'")
for _, row := range rows {
process(row)
}
CDC
: Lắng nghe và phản ứng trong thời gian thực.
func handleOrderEvent(e cdc.Event) {
if e.Table == "orders" && e.Change["status"] == "new" {
process(e.Change)
}
}
Thay vì quét tất cả các hàng sau mỗi khoảng thời gian, bạn chỉ phản ứng với những hàng đã thay đổi mà thôi.
So sánh: Polling và CDC
Chúng tôi đã thử nghiệm cả hai cách tiếp cận trong một hệ thống giống môi trường production, xử lý dữ liệu đơn hàng với 10.000 mục mới mỗi giờ.
Chỉ số | Cron (Mỗi 5 phút) | CDC (Debezium + Kafka) |
---|---|---|
Độ trễ trung bình | 150–300 giây | Dưới 1 giây |
Tải database (CPU %) | 38% | 4% |
Tỷ lệ sự kiện trùng lặp | ~5% (do chồng chéo/tranh chấp) | 0% |
Chi phí vận hành | Cao | Thấp |
CDC
đã giảm độ trễ từ vài phút xuống còn mili giây và giảm tải CPU trên database tới 8 lần.
Tại sao CDC lại thắng thế?
-
Phản hồi theo thời gian thực
CDC
truyền các thay đổi trong vòng mili giây. Người dùng thấy kết quả nhanh hơn. Các quy trình làm việc được kích hoạt ngay lập tức.Cron job
không thể cạnh tranh được khoản này. -
Giảm áp lực lên Database Các polling queries thường liên quan đến việc quét toàn bộ bảng hoặc index có lọc.
CDC
đọc từWrite-Ahead Log
, không phải từ chính bảng đó. -
Xử lý chính xác một lần (Exactly-Once Processing) Với Kafka và metadata của
CDC
(LSNs, timestamps), bạn có thể đạt được ngữ nghĩaidempotent
hoặcexactly-once
.Cron job
thường dẫn đến việc trùng lặp hoặc bỏ lỡ công việc do tranh chấp và thử lại. -
Khả năng phát lại Bỏ lỡ một sự kiện do hệ thống ngừng hoạt động? Với
CDC
qua Kafka, bạn chỉ cần quay ngược topic lại. Thử làm điều đó với mộtcron job
xem.
Khi nào Cron vẫn còn hữu ích?
- Lịch trình cố định: Chạy tác vụ này mỗi ngày vào lúc 2 giờ sáng.
- Các script dọn dẹp chạy một lần.
- Các tác nhân không phải database: API bên ngoài, file, hoặc xử lý hàng loạt mà log database không phù hợp.
Nhưng đối với dữ liệu bên trong database của bạn, CDC
là lựa chọn mặc định mới.
Bắt đầu với CDC như thế nào?
-
Thêm Debezium vào hệ thống của bạn: Sử dụng Kafka + Kafka Connect với connector Debezium cho database của bạn.
-
Xử lý sự kiện: Truyền chúng vào các dịch vụ của bạn bằng Kafka clients (Java, Go, vân vân).
-
Lọc và xử lý: Chỉ xử lý những thay đổi quan trọng. Sử dụng
operation
,before/after
,table
và các metadata khác.
Ví dụ: Consumer Go segmentio/kafka-go
for {
msg, _ := r.ReadMessage(ctx)
var evt CDCEvent
json.Unmarshal(msg.Value, &evt)
if evt.Table == "orders" && evt.After.Status == "new" {
processOrder(evt.After)
}
}
Nếu bạn vẫn đang phụ thuộc vào cron job
để điều khiển các quy trình nghiệp vụ, bạn đang xây dựng trên một nền tảng chậm chạp và dễ hỏng đó. Các hệ thống hiện đại là dựa trên sự kiện, chứ không phải dựa trên bộ đếm thời gian.
Cron job
thuộc về quá khứ rồi. CDC
mới là cách để bạn chắc ăn cho tương lai của hệ thống backend.