Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 42 — Backup & Disaster Recovery

Đã đọc 0/16 mục · còn khoảng 12 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Mở đầu — vì sao bài này quan trọng

Có một câu nói phũ phàng nhưng đúng trong ngành: "Không ai quan tâm đến backup, họ chỉ quan tâm đến restore." Bạn có thể chạy backup đều đặn suốt hai năm trời, nhưng nếu vào cái ngày định mệnh mà bản backup đó không khôi phục được, thì hai năm công sức coi như bằng không — và có khi cả sự nghiệp của bạn ở công ty đó cũng bằng không luôn.

Với vai trò một DevOps Engineer, backup và disaster recovery (DR) không phải là "việc của admin đời cũ" mà là trách nhiệm cốt lõi của bạn. Khi hệ thống chạy trên hàng chục container, dữ liệu nằm rải rác ở database managed, object storage, persistent volume trong Kubernetes, và cấu hình hạ tầng nằm trong Terraform state — thì một sự cố mất dữ liệu không còn là "khôi phục một file" mà là "dựng lại cả một hệ sinh thái". Bài này giúp bạn hiểu tư duy đo lường DR bằng hai con số quyết định mọi thứ — RPO và RTO — rồi từ đó thiết kế chiến lược backup phù hợp với ngân sách và mức độ chấp nhận rủi ro của doanh nghiệp.

Điều quan trọng nhất bạn cần thấm: backup không phải mục tiêu, mà là phương tiện. Mục tiêu là khả năng phục hồi hoạt động kinh doanh. Mọi quyết định kỹ thuật đều phải quy chiếu về câu hỏi: "Nếu mất, ta mất bao nhiêu, và mất bao lâu để quay lại?"

Khái niệm cốt lõi

RPO — Recovery Point Objective (mất bao nhiêu dữ liệu là chấp nhận được)

RPO trả lời câu hỏi: "Ta được phép mất tối đa bao nhiêu dữ liệu?" — đo bằng thời gian, tính ngược từ thời điểm sự cố.

Nếu RPO = 1 giờ, nghĩa là khi thảm họa xảy ra, ta chấp nhận mất tối đa 1 giờ dữ liệu gần nhất. Muốn đạt được điều này, tần suất backup (hoặc replication) phải ít nhất mỗi giờ một lần. Nếu bạn chỉ backup mỗi 24 giờ, thì RPO thực tế của bạn là 24 giờ — dù bạn có muốn hay không.

RPO trực tiếp quyết định chiến lược và tần suất sao lưu:

  • RPO = 24h → backup hằng ngày (snapshot đêm) là đủ.
  • RPO = 1h → cần incremental backup hoặc log shipping mỗi giờ.
  • RPO gần bằng 0 → cần replication đồng bộ/liên tục (synchronous replication, continuous archiving của WAL trong PostgreSQL).
RPO càng nhỏ thì chi phí càng cao, vì bạn phải sao chép dữ liệu thường xuyên hơn và duy trì hạ tầng phức tạp hơn.

RTO — Recovery Time Objective (mất bao lâu để quay lại)

RTO trả lời câu hỏi: "Ta được phép ngừng hoạt động tối đa bao lâu trước khi hệ thống trở lại?" — tính từ lúc sự cố xảy ra đến lúc dịch vụ chạy lại bình thường.

Nếu RTO = 4 giờ, bạn có 4 tiếng để phát hiện sự cố, quyết định, khôi phục dữ liệu, dựng lại hạ tầng và xác nhận hệ thống hoạt động. RTO quyết định kiến trúc phục hồi:

  • RTO = vài ngày → khôi phục thủ công từ backup lạnh (cold backup) trên object storage là chấp nhận được.
  • RTO = vài giờ → cần backup được kiểm thử, script phục hồi tự động, hạ tầng dựng bằng IaC sẵn sàng.
  • RTO = vài phút → cần hệ thống standby chạy song song (warm/hot standby), tự động failover.
Một sai lầm kinh điển là nhầm lẫn: RPO nói về dữ liệu bị mất, RTO nói về thời gian gián đoạn. Chúng độc lập với nhau. Bạn hoàn toàn có thể có RPO = 5 phút (gần như không mất dữ liệu) nhưng RTO = 8 tiếng (khôi phục rất lâu), hoặc ngược lại.

Cách doanh nghiệp chọn RPO/RTO

Đây không phải quyết định kỹ thuật thuần túy — nó là quyết định kinh doanh. Bạn hỏi business: "Nếu mất X giờ dữ liệu, hoặc chết Y giờ, thiệt hại là bao nhiêu tiền, bao nhiêu uy tín?" Một sàn thương mại điện tử vào ngày sale lớn có thể mất hàng tỷ đồng mỗi giờ downtime, nên RTO của họ phải tính bằng phút. Một blog nội bộ thì RTO một ngày cũng chẳng sao.

Các cấp độ DR (DR tiers)

Ngành thường phân bốn cấp chiến lược, đánh đổi giữa chi phí và tốc độ phục hồi:

  • Backup & Restore: backup lên object storage, khi sự cố thì dựng lại từ đầu. Rẻ nhất, RTO/RPO cao (giờ đến ngày).
  • Pilot Light: giữ một bản lõi tối thiểu (database replica, image) luôn chạy ở vùng dự phòng; khi cần thì "bật đèn" scale lên. RTO thấp hơn.
  • Warm Standby: chạy một phiên bản thu nhỏ của toàn hệ thống ở vùng dự phòng, sẵn sàng scale up. RTO tính bằng phút.
  • Hot Standby / Multi-site Active-Active: hai vùng cùng phục vụ traffic, mất một vùng gần như không gián đoạn. Đắt nhất, RTO/RPO gần bằng 0.

Quy tắc 3-2-1 — nền tảng của mọi backup

Đây là quy tắc bất tử: giữ 3 bản sao dữ liệu, trên 2 loại phương tiện/hệ thống khác nhau, với 1 bản đặt ở vị trí tách biệt (off-site, thường là vùng địa lý khác hoặc cloud khác). Phiên bản hiện đại thêm 3-2-1-1-0: một bản offline/immutable (chống ransomware) và 0 lỗi khi kiểm thử phục hồi.

Các loại backup

  • Full backup: sao chép toàn bộ. Chậm, tốn dung lượng, nhưng khôi phục đơn giản.
  • Incremental: chỉ sao chép thay đổi kể từ backup gần nhất. Nhanh, nhẹ, nhưng khôi phục phải ghép chuỗi.
  • Differential: sao chép thay đổi kể từ lần full backup gần nhất. Trung gian giữa hai loại trên.
  • Snapshot: ảnh chụp tức thời trạng thái volume/disk (rất phổ biến với EBS, GCP Persistent Disk, hoặc trong Kubernetes qua Velero).

Tình huống thực tế

Tình huống 1 — Startup fintech Việt Nam và bài học "backup không restore được"

Một startup ví điện tử tại TP.HCM (gọi là công ty A) chạy PostgreSQL trên EC2 tự quản. Team DevOps cấu hình pg_dump chạy mỗi đêm, đẩy file .sql.gz lên S3, và tự tin rằng "đã có backup". Suốt 14 tháng, mọi thứ bình thường.

Rồi một sáng, đĩa dữ liệu bị hỏng do lỗi filesystem. Team bình tĩnh lấy file dump mới nhất về restore — và phát hiện file bị cắt cụt (truncated). Hóa ra dung lượng database đã vượt disk tạm dùng để dump, script chạy fail âm thầm mỗi đêm suốt 3 tuần, nhưng không ai kiểm tra vì exit code bị nuốt trong một pipeline pg_dump | gzip (chỉ exit code của gzip được ghi nhận). Bản dump hợp lệ cuối cùng đã 3 tuần tuổi. RPO thực tế: 21 ngày, thay vì 24 giờ như họ tưởng.

Diễn giải: Họ có backup nhưng chưa bao giờ test restore, và pipeline che giấu lỗi. Hậu quả là mất 3 tuần giao dịch, phải đối soát thủ công với ngân hàng, tổn thất uy tín nặng nề.

Bài học: Backup chưa được kiểm thử restore = không có backup. Luôn dùng set -o pipefail trong script, luôn giám sát exit code và cảnh báo khi backup fail, và lên lịch restore drill định kỳ.

Tình huống 2 — Sàn TMĐT chọn RPO/RTO theo tiền, không theo cảm tính

Một sàn TMĐT khu vực Đông Nam Á (giả định là công ty B, tương tự mô hình Tiki/Shopee) cần định RPO/RTO cho hệ thống đặt hàng. Team ban đầu muốn "RPO = 0, RTO = 0 cho chắc". Nhưng khi ngồi tính chi phí, multi-region active-active cho toàn bộ stack đội chi phí hạ tầng lên gấp 2,3 lần.

Họ chia dữ liệu theo mức độ quan trọng (tiering):

  • Dữ liệu đơn hàng & thanh toán (tối quan trọng): RPO = 0 nhờ synchronous replication PostgreSQL cross-AZ, RTO = 15 phút với warm standby ở region khác.
  • Catalog sản phẩm (quan trọng vừa): RPO = 1h, RTO = 2h, backup + restore.
  • Log phân tích, ảnh review (ít quan trọng): RPO = 24h, RTO = 1 ngày.
Diễn giải: Bằng cách phân tầng, họ tập trung tiền vào đúng chỗ đau nhất và tiết kiệm đáng kể ở phần ít quan trọng.

Bài học: Không phải mọi dữ liệu đều đáng giá như nhau. RPO/RTO nên gắn với giá trị kinh doanh của từng loại dữ liệu, không cào bằng.

Tình huống 3 — Ransomware và giá trị của bản backup immutable

Một công ty logistics ở Hà Nội (công ty C) bị tấn công ransomware. Kẻ tấn công xâm nhập được vào cả server production lẫn NAS backup nội bộ, mã hóa sạch. May mắn, team DevOps đã bật S3 Object Lock (immutable/WORM) cho bản backup off-site với retention 30 ngày — kẻ tấn công dù có credential cũng không thể xóa hay sửa các bản này.

Họ khôi phục từ bản immutable của 6 giờ trước sự cố, mất khoảng 6 giờ dữ liệu (đúng bằng RPO đã thiết kế) và 5 giờ để dựng lại hệ thống. Nếu không có bản immutable off-site, họ đã phải trả tiền chuộc hoặc mất trắng.

Bài học: Trong kỷ nguyên ransomware, một bản backup immutable, tách biệt về quyền truy cập không còn là "nice to have". Backup nằm chung mạng/chung credential với production thì rất dễ chết cùng production.

Hướng dẫn từng bước

Đây là quy trình thiết kế và triển khai một chiến lược Backup & DR bài bản:

Bước 1 — Kiểm kê dữ liệu (data inventory). Liệt kê mọi nguồn dữ liệu stateful: database (Postgres, MySQL, MongoDB), object storage, persistent volume trong Kubernetes, secrets/config, và cả Terraform state. Lưu ý: Terraform state là một điểm hay bị quên — mất nó bạn sẽ mất khả năng quản lý hạ tầng bằng IaC.

Bước 2 — Định RPO/RTO cho từng nhóm dữ liệu. Ngồi với business, phân tầng như tình huống 2. Ghi lại thành bảng rõ ràng: mỗi nhóm dữ liệu → RPO → RTO → chiến lược tương ứng.

Bước 3 — Chọn chiến lược và công cụ theo từng nguồn:

  • Database managed (RDS, Cloud SQL): bật automated backup + point-in-time recovery (PITR), cấu hình retention khớp với RPO.
  • Kubernetes: dùng Velero để backup resource (YAML) + snapshot persistent volume, đẩy lên object storage off-site.
  • Object storage: bật versioning + cross-region replication + Object Lock.
  • Terraform state: dùng remote backend (S3) có versioning + state locking (DynamoDB).
Bước 4 — Áp dụng quy tắc 3-2-1. Đảm bảo có bản off-site (khác region/khác provider) và ít nhất một bản immutable.

Bước 5 — Tự động hóa và giám sát. Viết backup thành job có lịch (CronJob trong K8s hoặc cron hệ thống), dùng set -euo pipefail, và cảnh báo khi backup fail — im lặng khi thành công, la làng khi thất bại. Đừng quên giám sát cả "backup có mới không" (nếu bản mới nhất cũ hơn RPO → alert).

Bước 6 — Viết runbook phục hồi. Tài liệu từng bước restore: lệnh cụ thể, thứ tự khôi phục (thường: hạ tầng → database → application → cache), người chịu trách nhiệm. Runbook phải đủ rõ để một người trực đêm chưa từng làm cũng theo được.

Bước 7 — Test restore định kỳ (DR drill). Đây là bước quan trọng nhất và hay bị bỏ nhất. Lên lịch drill hằng quý: khôi phục vào môi trường tách biệt, đo thời gian thực tế (so với RTO cam kết), kiểm tra tính toàn vẹn dữ liệu (so với RPO). Ghi lại kết quả, rút kinh nghiệm, cập nhật runbook.

Lỗi thường gặp & mẹo

  • Chỉ backup mà không bao giờ restore thử. Đây là lỗi số một, như công ty A. Backup không test là niềm tin mù quáng. Mẹo: đặt lịch drill như một nghĩa vụ bắt buộc, coi "thời gian restore thực tế" là một metric được theo dõi.
  • Nuốt lỗi trong pipeline. pg_dump | gzip > file che giấu lỗi của pg_dump. Luôn set -o pipefail, kiểm tra kích thước file backup so với ngưỡng kỳ vọng, và verify checksum.
  • Backup nằm chung "vùng chết" với production. Cùng account, cùng region, cùng credential → một sự cố (hoặc một kẻ tấn công) xóa cả hai. Luôn có bản off-site và immutable.
  • Quên backup Terraform state và secrets. Khôi phục được database nhưng không dựng lại được hạ tầng thì RTO vẫn nổ. Đưa state và secret vào phạm vi backup.
  • Nhầm replication là backup. Replication chép cả lỗi: nếu ai đó lỡ DROP TABLE, lệnh đó được nhân bản sang replica ngay lập tức. Backup có time-travel (PITR, snapshot lịch sử) mới cứu được lỗi con người.
  • RPO/RTO chỉ nằm trên giấy. Cam kết RTO 1h nhưng chưa từng đo thực tế thì con số đó vô nghĩa. Mẹo: mỗi drill là một lần "kiểm định" lại cam kết.
  • Không định nghĩa retention hợp lý. Giữ backup quá ngắn thì không đủ để phát hiện lỗi âm thầm; giữ quá dài thì đội chi phí. Thường dùng chính sách phân tầng: giữ dày ở gần (hằng ngày trong 30 ngày), thưa dần về xa (hằng tháng trong 1 năm).

Bài tập thực hành

  • Định RPO/RTO cho một hệ thống giả định. Cho một ứng dụng đặt lịch khám bệnh online tại Việt Nam gồm: database bệnh nhân/lịch hẹn, ảnh chụp X-quang lưu trên object storage, log truy cập. Hãy phân tầng và đề xuất RPO/RTO cho từng nhóm, kèm lý do kinh doanh.
  • Viết script backup Postgres an toàn. Viết một shell script backup PostgreSQL, đẩy lên S3, có set -euo pipefail, kiểm tra kích thước file tối thiểu, ghi log, và trả về exit code khác 0 (kèm cảnh báo) khi thất bại. Suy nghĩ: bạn sẽ giám sát "backup fail" bằng cách nào?
  • Thiết kế 3-2-1 cho một cụm Kubernetes. Mô tả bạn sẽ dùng Velero như thế nào để đạt 3-2-1: đâu là 3 bản sao, 2 loại phương tiện, 1 bản off-site immutable. Vẽ sơ đồ luồng.
  • Lập kịch bản DR drill. Viết checklist cho một buổi diễn tập khôi phục toàn hệ thống: mục tiêu đo lường (RTO/RPO thực tế), môi trường tách biệt, thứ tự khôi phục, tiêu chí "pass/fail".

Tóm tắt

  • RPO (Recovery Point Objective) đo lượng dữ liệu tối đa được phép mất, tính bằng thời gian — quyết định tần suất backup/replication.
  • RTO (Recovery Time Objective) đo thời gian gián đoạn tối đa cho phép — quyết định kiến trúc phục hồi (backup-restore, pilot light, warm/hot standby).
  • Hai chỉ số này độc lập, và phải được chọn dựa trên giá trị kinh doanh, tốt nhất là phân tầng theo từng loại dữ liệu.
  • Quy tắc 3-2-1 (3 bản, 2 phương tiện, 1 off-site) là nền tảng; thời hiện đại thêm immutable/offline để chống ransomware.
  • Phân biệt full/incremental/differential/snapshot, và nhớ replication không phải backup vì nó nhân bản cả lỗi.
  • Chân lý cốt lõi: backup chưa test restore = không có backup. Tự động hóa, giám sát lỗi backup, viết runbook, và diễn tập DR định kỳ là những việc phân biệt một hệ thống "trông có vẻ an toàn" với một hệ thống thực sự phục hồi được.
Hãy nhớ: đến ngày bạn cần restore, mọi thứ đều muộn để chuẩn bị. Sự bình tĩnh trong khủng hoảng đến từ những buổi diễn tập nhàm chán trước đó.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi