0

Elasticsearch Bài học 43: Snapshot & Restore - Chiến lược Backup dữ liệu Elasticsearch an toàn

Trong kiến trúc hệ thống, rất nhiều Backend Engineer có một sự hiểu lầm chết người: "Cụm Elasticsearch của tôi có 3 Node, đã cấu hình Replica đầy đủ. Nếu chết 1 Node, Node khác sẽ tự động gánh. Vậy tôi không cần Backup nữa!"

Sai lầm! Replica sinh ra để chống lại sự cố phần cứng (Hardware Failure) và đảm bảo tính sẵn sàng cao (High Availability). Nhưng Replica hoàn toàn vô dụng trước Lỗi con người (Human Error).

Hãy tưởng tượng một ngày đẹp trời, một Dev mới vào team vô tình chạy nhầm lệnh DELETE /products trên Production. Ngay lập tức, lệnh xóa này sẽ được Master Node đồng bộ sang tất cả các Replica Shards. Toàn bộ dữ liệu bốc hơi trong 1 giây ở mọi Node.

Để cứu vãn những thảm họa "xóa nhầm" hoặc Data Center bị cháy nổ diện rộng, chúng ta bắt buộc phải có một cơ chế sao lưu độc lập ra bên ngoài. Đó là Snapshot & Restore.

1. Bản chất của Snapshot: Backup tăng dần (Incremental)

Nếu bạn đã từng dùng mysqldump để backup MySQL, bạn sẽ biết nó mệt mỏi thế nào. Bảng có 100GB, mỗi lần dump là phải copy toàn bộ 100GB đó ra file SQL.

Snapshot của Elasticsearch thông minh hơn rất nhiều. Nó hoạt động theo cơ chế Incremental (Tăng dần) dựa trên các Segment của Inverted Index.

  • Ngày 1 (Full Backup): Index của bạn có 5 Segment (tổng 100GB). Elasticsearch sẽ copy cả 100GB này lên S3.

  • Ngày 2 (Incremental Backup): Hệ thống có thêm dữ liệu, sinh ra thêm 1 Segment mới (5GB). Khi bạn gọi lệnh Snapshot lần 2, Elasticsearch KHÔNG copy lại 100GB cũ. Nó chỉ copy đúng cái Segment 5GB mới lên S3, và tạo các con trỏ (pointer) trỏ về 5 Segment cũ.

Nhờ vậy, bạn có thể chạy Snapshot mỗi giờ một lần mà không sợ tốn băng thông mạng hay phình to dung lượng ổ cứng lưu trữ.

2. Bước 1: Đăng ký Kho lưu trữ (Snapshot Repository)

Elasticsearch không cho phép bạn lưu Snapshot lung tung. Bạn phải cấu hình một "Kho chứa" (Repository). Kho này phải nằm NGOÀI cụm Elasticsearch. Phổ biến nhất là AWS S3, Google Cloud Storage, hoặc MinIO (nếu chạy On-premise).

Giả sử chúng ta dùng AWS S3. Trước tiên, bạn cài đặt plugin repository-s3 trên tất cả các Node, sau đó khai báo kho chứa bằng API:

JSON

PUT _snapshot/s3_hasaki_backup
{
  "type": "s3",
  "settings": {
    "bucket": "hasaki-es-backups-2026",
    "client": "default", 
    "compress": true
  }
}

(client: default sẽ tự động lấy thông tin Access Key / Secret Key mà bạn đã cài đặt trong Keystore của Elasticsearch).

3. Bước 2: Thực thi chụp Snapshot (Backup)

Khi kho đã sẵn sàng, việc tạo Snapshot chỉ tốn của bạn đúng 1 dòng lệnh.

JSON

PUT _snapshot/s3_hasaki_backup/snapshot_2026_10_17?wait_for_completion=false
{
  "indices": "products,afc_logs-000001",
  "ignore_unavailable": true,
  "include_global_state": false
}

Giải mã cấu hình:

  • indices: Chỉ định đích danh các Index cần backup. Nếu để trống, nó sẽ backup TOÀN BỘ hệ thống (rất nặng).

  • ignore_unavailable: Bỏ qua lỗi nếu có Index nào đó trong list không tồn tại.

  • include_global_state: false: Mặc định, Elasticsearch sẽ lưu luôn cả trạng thái Cluster, Templates, ILM Policies. Nhưng nếu bạn chỉ muốn backup data của Index, hãy set false.

  • wait_for_completion=false: Lệnh này sẽ trả về ngay lập tức (Async) để không làm treo Terminal của bạn. Quá trình copy lên S3 sẽ âm thầm chạy ở background.

4. Bước 3: Phục hồi dữ liệu (Restore) - Cứu tinh trong đêm

Khi thảm họa xảy ra (Ví dụ: products bị xóa hoặc dữ liệu bị hỏng), bạn cần lôi bản Snapshot mới nhất về.

Quy tắc sinh tử: Bạn KHÔNG THỂ restore đè lên một Index đang Mở (Open) và đang hoạt động.

  • Nếu Index cũ vẫn còn (nhưng dữ liệu bị sai), bạn phải Đóng nó lại (POST /products/_close) rồi mới Restore.

  • An toàn nhất: Hãy Restore nó ra một cái tên hoàn toàn mới, kiểm tra dữ liệu ok rồi mới dùng Alias (Bài 22) trỏ hệ thống sang Index phục hồi.

Cú pháp Restore ra tên mới:

JSON

POST _snapshot/s3_hasaki_backup/snapshot_2026_10_17/_restore
{
  "indices": "products",
  "rename_pattern": "(.+)",
  "rename_replacement": "restored_$1", 
  "ignore_index_settings": [
    "index.refresh_interval" 
  ]
}

Lệnh trên sẽ tìm Index products bên trong Snapshot, lôi nó về và đặt tên thành restored_products.

5. Tự động hóa với SLM (Snapshot Lifecycle Management)

Việc tự gõ lệnh API tạo Snapshot mỗi ngày là cực kỳ thiếu chuyên nghiệp và rủi ro (lỡ bạn quên thì sao?).

Thay vì phải viết cronjob trên server Linux, Elasticsearch cung cấp SLM (Snapshot Lifecycle Management). Nó cho phép bạn lập lịch chụp ảnh tự động bằng chuẩn Cron Expression, đồng thời tự động xóa các Snapshot quá cũ để S3 không bị đầy (Retention).

Cấu hình một SLM Policy chạy vào 2h sáng mỗi ngày:

JSON

PUT _slm/policy/daily_backup_policy
{
  "schedule": "0 0 2 * * ?", // Chạy lúc 2:00 AM hàng ngày
  "name": "<daily-backup-{now/d}>", // Tự động lấy ngày tháng gán vào tên (VD: daily-backup-2026.10.17)
  "repository": "s3_hasaki_backup",
  "config": {
    "indices": ["*"], // Backup toàn bộ
    "include_global_state": true
  },
  "retention": {
    "expire_after": "30d", // Xóa các bản Snapshot cũ hơn 30 ngày trên S3
    "min_count": 5,        // Nhưng LUÔN LUÔN giữ lại ít nhất 5 bản dù thế nào đi nữa
    "max_count": 50        // Và tối đa chỉ giữ 50 bản để tiết kiệm tiền AWS
  }
}

Nhờ có SLM, hệ thống phòng thủ của bạn đã được tự động hóa hoàn toàn. Bạn có thể yên tâm ngủ ngon mà không sợ mất dữ liệu.

Tuy nhiên, Backup chỉ là phương án cứu hộ. Để hệ thống không bao giờ phải đi đến bước đó, Master Node cần phải hoạt động cực kỳ ổn định. Nếu Master Node "ngáo", Cluster của bạn sẽ vỡ thành hai mảnh (Split-brain) - mỗi mảnh tự nhận mình là một Cluster riêng biệt, dẫn đến dữ liệu bị ghi đè loạn xạ. Bài tiếp theo sẽ giải quyết vấn đề hệ thống cốt lõi này.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí