Mở đầu — vì sao bài này quan trọng
Suốt các bài trước, bạn đã học cách vận hành hệ thống web: uptime 99.9%, latency thấp, request phải trả về trong vài chục mili-giây. Nhưng có một mảng vận hành rất khác, thường bị các SRE "web-native" xem nhẹ, đó là Data Pipeline Operations — vận hành các đường ống dữ liệu.
Tại sao lại quan trọng? Vì gần như mọi công ty ngày nay đều chạy trên dữ liệu. Báo cáo doanh thu buổi sáng cho ban giám đốc, dashboard theo dõi đơn hàng của đội vận hành, mô hình chấm điểm tín dụng của fintech, tính năng gợi ý sản phẩm của sàn thương mại điện tử — tất cả đều được nuôi bằng các pipeline dữ liệu chạy ngầm. Khi pipeline hỏng, người dùng không nhận được lỗi 500 ngay lập tức. Thay vào đó, họ nhận một con số sai hoặc một báo cáo trễ, và điều đó nguy hiểm hơn nhiều vì nó âm thầm.
Điều khiến data pipeline khác biệt là bộ tiêu chí đánh giá "khỏe mạnh" của nó hoàn toàn không giống web ops. Ở web ops, bạn ám ảnh với latency và uptime. Ở data ops, bạn ám ảnh với correctness (dữ liệu có đúng không) và freshness (dữ liệu có mới không). Một pipeline chạy chậm 2 giây chẳng ai quan tâm; nhưng một pipeline nạp trùng dữ liệu khiến doanh thu bị đếm gấp đôi thì có thể khiến CEO ra quyết định sai lầm.
Trong bài này, chúng ta sẽ đi sâu vào cách vận hành pipeline với hai công cụ phổ biến nhất hiện nay: Airflow (điều phối luồng công việc — orchestration) và dbt (biến đổi dữ liệu trong kho — transformation). Bạn sẽ hiểu cách định nghĩa SLO cho dữ liệu, cách phát hiện sự cố sớm, và cách xử lý khi backfill hàng terabyte dữ liệu lúc 3 giờ sáng.
Khái niệm cốt lõi
Data Ops khác Web Ops ở đâu
Hãy khắc sâu ba khác biệt nền tảng, vì chúng quyết định toàn bộ cách bạn thiết kế monitoring và SLO.
Thứ nhất, latency không phải ngôi sao — correctness và freshness mới là. Trong web ops, một request 500ms là chậm. Trong data ops, một job ETL chạy 3 tiếng là hoàn toàn bình thường, miễn là nó xong trước hạn. Câu hỏi quan trọng không phải "nhanh cỡ nào" mà là "dữ liệu có đúng không" và "dữ liệu mới đến đâu".
Thứ hai, SLO được diễn đạt theo thời hạn (deadline), không phải theo phần trăm uptime. Thay vì "hệ thống up 99.9%", data team nói: "Bảng doanh thu ngày hôm qua phải sẵn sàng (ready) trước 8 giờ sáng mỗi ngày, ít nhất 99% số ngày trong quý." Đây gọi là data freshness SLO. Deadline này thường bám theo nhịp làm việc của con người: sếp mở laptop lúc 8h30, dashboard phải đã cập nhật.
Thứ ba, pipeline có tính phụ thuộc dây chuyền (dependency). Bảng A nạp xong mới tới bảng B, B xong mới tới C. Nếu A trễ 1 tiếng, cả dây chuyền lệch. Đây là lý do orchestration trở thành trái tim của data ops — bạn cần một "nhạc trưởng" biết bảng nào chạy trước, bảng nào chạy sau, và retry ra sao khi một mắt xích hỏng.
Airflow — người điều phối (orchestrator)
Apache Airflow là công cụ điều phối workflow phổ biến nhất. Ý tưởng cốt lõi là DAG (Directed Acyclic Graph — đồ thị có hướng, không vòng lặp). Mỗi DAG là một luồng công việc gồm nhiều task, và Airflow biết thứ tự chạy dựa trên quan hệ phụ thuộc bạn khai báo.
Ví dụ đơn giản: task extract_orders → transform_orders → load_to_warehouse → send_report. Airflow chạy tuần tự, tự retry khi lỗi, và ghi log từng lần chạy.
Vài khái niệm vận hành bạn phải nắm:
- Schedule interval: DAG chạy theo lịch (ví dụ
@daily, hoặc cron0 2 *— 2h sáng mỗi ngày). - Execution date / logical date: Airflow phân biệt "ngày dữ liệu" và "ngày chạy thực tế". Một điểm cực dễ gây bug — job chạy sáng nay 2h thường xử lý dữ liệu của hôm qua.
- Retry & SLA: Bạn cấu hình số lần retry, khoảng nghỉ giữa các lần, và SLA miss — Airflow gửi cảnh báo nếu task chạy quá thời gian cho phép.
- Backfill: Chạy lại DAG cho một khoảng thời gian trong quá khứ — nghiệp vụ vận hành nhạy cảm nhất, sẽ nói kỹ ở phần sau.
- Idempotency (tính bất biến khi lặp): Task phải viết sao cho chạy lại nhiều lần vẫn ra cùng kết quả, không nhân đôi dữ liệu.
dbt — người biến đổi (transformation)
dbt (data build tool) không di chuyển dữ liệu; nó biến đổi dữ liệu đã nằm trong kho (warehouse như BigQuery, Snowflake, Redshift). Bạn viết các model bằng SQL, dbt lo việc dựng bảng theo đúng thứ tự phụ thuộc và — quan trọng cho vận hành — chạy tests để kiểm tra chất lượng dữ liệu.
Những khả năng dbt mà một người làm ops cần biết:
- Tests:
unique,not_null,accepted_values,relationships. Ví dụ, testnot_nulltrên cộtorder_idsẽ fail nếu có đơn hàng thiếu ID. Đây chính là "cầu chì" bảo vệ correctness. - Snapshots: Theo dõi thay đổi dữ liệu theo thời gian (slowly changing dimensions).
- Freshness check: dbt có thể kiểm tra dữ liệu nguồn đã cũ bao lâu — nền tảng để thực thi freshness SLO.
- Lineage (dòng dõi dữ liệu): dbt tự vẽ đồ thị bảng nào phụ thuộc bảng nào, giúp bạn biết nếu bảng gốc hỏng thì bảng nào bị ảnh hưởng.
dbt run và dbt test như một task trong DAG. Airflow lo "khi nào chạy, chạy lại ra sao"; dbt lo "biến đổi thế nào, dữ liệu có sạch không".SLO cho dữ liệu: freshness, completeness, correctness
Ba trục SLO bạn nên định nghĩa:
- Freshness (độ tươi): Dữ liệu mới đến mức nào? "Bảng
fct_orderskhông được cũ quá 6 tiếng." - Completeness (độ đầy đủ): Có đủ dữ liệu không? "Số dòng nạp hôm nay không được thấp hơn 80% trung bình 7 ngày." — bẫy phát hiện khi nguồn dữ liệu bị mất một phần.
- Correctness (độ đúng): Dữ liệu có hợp lệ không? Đây là nơi dbt tests phát huy — không trùng khóa, không null ở cột bắt buộc, tổng doanh thu khớp với hệ thống nguồn.
Tình huống thực tế
Ví dụ 1 — Báo cáo doanh thu 8h sáng của một sàn TMĐT tại TP.HCM
Một sàn thương mại điện tử giả định, gọi là ShopViet, có một DAG Airflow chạy lúc 2h sáng: kéo dữ liệu đơn hàng từ MySQL production sang BigQuery, rồi chạy dbt run để dựng bảng daily_revenue, cuối cùng đẩy vào dashboard cho ban giám đốc xem lúc 8h.
Một sáng thứ Hai, giám đốc vận hành mở dashboard và thấy doanh thu Chủ Nhật chỉ bằng 60% bình thường. Hoảng loạn ban đầu: "Có phải chương trình khuyến mãi thất bại?". Đội data vào điều tra và phát hiện: đêm đó database production bị chậm, task extract_orders timeout ở giữa chừng, chỉ kéo được một phần đơn hàng. Nhưng vì task được viết không idempotent và không kiểm tra completeness, nó vẫn "thành công" một phần và bảng vẫn được dựng với dữ liệu thiếu.
Diễn giải: Vấn đề không phải hệ thống "down" — dashboard vẫn hiển thị bình thường, chỉ là con số sai. Đây chính là mối nguy đặc trưng của data ops: sự cố im lặng.
Bài học: Họ thêm một dbt test kiểu completeness — số đơn hàng hôm nay không được thấp hơn 70% trung bình 7 ngày; nếu vi phạm, DAG dừng lại và cảnh báo, không xuất bản bảng ra dashboard. Nguyên tắc vàng: thà báo cáo trễ còn hơn báo cáo sai — trễ thì người ta chờ, sai thì người ta ra quyết định nhầm.
Ví dụ 2 — Fintech và cuộc backfill 3 giờ sáng
Một công ty fintech tại Singapore chạy mô hình chấm điểm rủi ro dựa trên bảng user_transactions do dbt dựng. Một ngày, đội data phát hiện suốt 10 ngày qua có một lỗi logic trong model SQL: phí giao dịch bị tính sai đơn vị tiền tệ (nhầm giữa VND và SGD ở một nhánh dữ liệu). Toàn bộ 10 ngày dữ liệu cần được backfill — chạy lại để sửa.
Kỹ sư trực on-call chạy dbt run --full-refresh lúc 3h sáng. Vấn đề: bảng này lớn 2 TB, và full-refresh nghĩa là dựng lại toàn bộ từ đầu. Job ngốn hết capacity của warehouse, khiến các pipeline khác chạy song song bị treo, và chi phí BigQuery của ngày hôm đó tăng vọt gấp 8 lần bình thường.
Diễn giải: Backfill là con dao hai lưỡi. Nó cần thiết để sửa dữ liệu, nhưng nếu làm bừa, nó tạo ra sự cố còn lớn hơn sự cố ban đầu.
Bài học: Backfill phải được giới hạn phạm vi (chỉ 10 ngày lỗi, không phải toàn bộ lịch sử) và chia nhỏ (mỗi lần một ngày, không phải một cú full-refresh). Họ chuyển model sang chế độ incremental với khả năng backfill theo từng partition ngày, và đặt quy tắc: mọi backfill trên 500 GB phải được review, không tự ý chạy lúc rạng sáng. Đây cũng là điểm giao với change management — backfill lớn nên được xem là một "change" có risk tier cao.
Ví dụ 3 — Data pipeline "thành công thầm lặng" nhưng không có dữ liệu
Một startup logistics ở Hà Nội có pipeline Airflow kéo dữ liệu GPS xe tải từ một API bên thứ ba mỗi giờ. Suốt hai tuần, tất cả các task đều xanh (success) trên Airflow UI. Nhưng đội phân tích phàn nàn dashboard vị trí xe "đứng hình".
Điều tra ra: nhà cung cấp API đã âm thầm đổi endpoint, trả về mã 200 kèm một mảng rỗng []. Task Airflow nhận 200, coi như thành công, nạp 0 dòng, và báo xanh vui vẻ suốt hai tuần.
Diễn giải: "Task success" không đồng nghĩa với "data healthy". Airflow chỉ biết code chạy xong không lỗi; nó không biết dữ liệu có ý nghĩa hay không.
Bài học: Thêm data quality gate — một task kiểm tra số dòng nạp phải lớn hơn 0 (và tốt hơn là nằm trong khoảng kỳ vọng). Đồng thời bật freshness monitoring ở tầng bảng: nếu bảng vehicle_locations không có dữ liệu mới trong 2 tiếng, cảnh báo bất kể task Airflow báo gì. Monitor dữ liệu, đừng chỉ monitor job.
Hướng dẫn từng bước
Đây là quy trình thiết lập vận hành cơ bản cho một data pipeline mới:
Bước 1 — Xác định SLO dữ liệu trước khi code. Ngồi với người dùng cuối (business) và hỏi: "Dữ liệu này cần sẵn sàng lúc mấy giờ? Cũ nhất được bao nhiêu?". Viết ra freshness SLO cụ thể, ví dụ "daily_revenue ready trước 7h30, dữ liệu không cũ quá 24 giờ, đạt 99% số ngày/quý."
Bước 2 — Thiết kế DAG với task idempotent. Mỗi task phải chạy lại được mà không nhân đôi dữ liệu. Kỹ thuật phổ biến: dùng pattern DELETE partition rồi INSERT thay vì INSERT thuần, hoặc MERGE/upsert theo khóa. Khai báo rõ dependency giữa các task.
Bước 3 — Cắm dbt tests làm cầu chì. Với mỗi bảng quan trọng, thêm tối thiểu: unique + not_null trên khóa chính, relationships cho khóa ngoại, và một test completeness (số dòng trong khoảng hợp lý). Đặt dbt test là task chạy sau dbt run và trước khi xuất bản.
Bước 4 — Bật freshness check và SLA miss alert. Cấu hình dbt source freshness cho các nguồn, và đặt SLA trong Airflow để nhận cảnh báo khi task chạy quá deadline. Alert phải bắn vào kênh on-call (Slack/Telegram/PagerDuty), không chỉ email dễ bị bỏ qua.
Bước 5 — Thiết kế sẵn quy trình backfill. Trước khi lên production, hãy trả lời: "Nếu phát hiện dữ liệu sai 30 ngày, tôi backfill thế nào?". Đảm bảo model hỗ trợ backfill theo partition, có giới hạn phạm vi, và có runbook rõ ràng cho on-call.
Bước 6 — Xây dashboard sức khỏe pipeline. Theo dõi: tỉ lệ DAG thành công, thời gian chạy trung bình (để phát hiện job phình dần), độ trễ freshness, và chi phí warehouse theo ngày. Đây là "golden signals" phiên bản data ops.
Lỗi thường gặp & mẹo
Lỗi 1 — Monitor job thay vì monitor data. Task xanh không có nghĩa dữ liệu đúng. Luôn có ít nhất một tầng kiểm tra ở mức dữ liệu (row count, freshness, giá trị hợp lý).
Lỗi 2 — Task không idempotent. Retry hoặc backfill sẽ nhân đôi dữ liệu. Mẹo: thiết kế mọi task viết dữ liệu theo kiểu "xóa partition rồi ghi lại" hoặc upsert theo khóa, để chạy lại bao nhiêu lần cũng ra một kết quả.
Lỗi 3 — Backfill full-refresh vô tội vạ. Gây quá tải warehouse và đội chi phí. Mẹo: luôn giới hạn phạm vi thời gian, chia nhỏ theo ngày, và coi backfill lớn như một change có rủi ro cao cần review.
Lỗi 4 — SLO dữ liệu diễn đạt kiểu uptime. "Pipeline up 99.9%" vô nghĩa với business. Hãy nói theo deadline: "ready trước 8h" — đó mới là ngôn ngữ họ hiểu và đo được.
Lỗi 5 — Bỏ qua schema drift. Nguồn dữ liệu đổi kiểu cột, thêm/bớt trường mà không báo trước. Mẹo: thêm test kiểm tra schema và cảnh báo sớm khi cấu trúc nguồn thay đổi.
Lỗi 6 — Nhầm execution date với run date trong Airflow. Đây là nguyên nhân kinh điển khiến job xử lý nhầm ngày dữ liệu. Luôn dùng biến ngày do Airflow cung cấp, đừng tự lấy today() trong code.
Mẹo vàng: Áp dụng nguyên tắc "fail loud, fail early" — thà pipeline dừng sớm và la lớn còn hơn âm thầm nạp dữ liệu rác. Trong data ops, im lặng là kẻ thù nguy hiểm nhất.
Bài tập thực hành
- Viết freshness SLO: Chọn một báo cáo thực tế trong công ty bạn (hoặc giả định) và viết ra SLO dữ liệu đầy đủ ba trục: freshness (deadline cụ thể), completeness (ngưỡng số dòng), correctness (những test cần có). Diễn đạt bằng ngôn ngữ business, không dùng "uptime".
- Thiết kế DAG idempotent: Phác thảo một DAG Airflow 4 task (extract → transform → test → publish) cho pipeline đơn hàng hằng ngày. Chỉ rõ mỗi task đảm bảo idempotency bằng cách nào, và task
testsẽ chặnpublishtrong tình huống nào.
- Lập runbook backfill: Viết runbook ngắn cho tình huống "phát hiện dữ liệu sai 14 ngày qua". Bao gồm: cách giới hạn phạm vi, cách chia nhỏ để không quá tải warehouse, ai cần approve, và cách xác minh dữ liệu đúng sau khi backfill xong.
- Phân tích sự cố im lặng: Đọc lại Ví dụ 3 (startup logistics). Ngoài data quality gate và freshness monitoring, hãy liệt kê thêm 2 cơ chế phòng thủ khác giúp phát hiện sớm khi API nguồn đổi hành vi.
Tóm tắt
Data Pipeline Operations là một nhánh vận hành với "hệ giá trị" khác hẳn web ops: bạn không đo bằng latency và uptime, mà bằng correctness (dữ liệu đúng), freshness (dữ liệu mới), và completeness (dữ liệu đủ). SLO được diễn đạt theo deadline con người — "ready trước 8h sáng" — chứ không phải phần trăm uptime trừu tượng.
Hai công cụ trụ cột là Airflow (điều phối DAG, lịch chạy, retry, backfill) và dbt (biến đổi SQL trong kho, và quan trọng nhất là tests + freshness check làm cầu chì chất lượng). Mô hình phổ biến là Airflow điều phối, dbt biến đổi.
Ba bài học lớn từ thực tế: (1) monitor dữ liệu chứ đừng chỉ monitor job — task xanh không đảm bảo dữ liệu đúng; (2) mọi task phải idempotent để retry và backfill an toàn; (3) backfill phải giới hạn phạm vi và chia nhỏ, coi như một change rủi ro cao. Và trên hết, hãy nhớ nguyên tắc xuyên suốt: thà dữ liệu trễ còn hơn dữ liệu sai — vì trong data ops, sự cố im lặng mới là kẻ thù nguy hiểm nhất.