0

Elasticsearch Bài học 42: Kiến trúc Data Tiers - Phân bổ Hot, Warm, Cold và Frozen Nodes tiết kiệm chi phí

Ở Bài 41, chúng ta đã dùng ILM để tự động xoay vòng (Rollover) các Index log của hệ thống AFC Metro Line 1. Tuy nhiên, ILM mới chỉ giải quyết bài toán "khi nào thì cắt file", chứ chưa giải quyết được bài toán "Tiền".

Hãy làm một bài toán kinh tế: Một cụm Elasticsearch chạy trên AWS. Bạn đang dùng ổ cứng SSD IOPS cao cực kỳ đắt đỏ để ghi dữ liệu. Nếu bạn giữ toàn bộ log của 1 năm qua trên ổ SSD đó, chi phí hàng tháng có thể lên tới hàng ngàn đô la. Trong khi thực tế, 90% các truy vấn (search/dashboard) chỉ tập trung vào dữ liệu của 7 ngày gần nhất. Các log từ 3 tháng trước hầu như không ai đụng tới, trừ khi có thanh tra (Audit) cần kiểm tra lại lỗi thẻ từ.

Việc lưu log 3 tháng tuổi trên ổ SSD là một sự lãng phí khủng khiếp. Để giải quyết bài toán này, Elasticsearch giới thiệu kiến trúc Data Tiers (Phân tầng dữ liệu).

1. Data Tiers là gì?

Thay vì mua 10 con server đắt tiền y hệt nhau, bạn sẽ thiết kế cụm (Cluster) thành các "Khu vực" (Tiers) với cấu hình phần cứng khác nhau. Dữ liệu sẽ chảy từ khu vực đắt tiền nhất (khi còn mới) xuống khu vực rẻ tiền nhất (khi đã cũ).

Từ phiên bản Elasticsearch 7.10 trở đi, có 4 tầng dữ liệu tiêu chuẩn: Hot, Warm, Cold, và Frozen.

Tầng 1: Hot Tier (Chiến binh tiền tuyến)

  • Nhiệm vụ: Hứng toàn bộ lượng dữ liệu mới đang Ghi (Indexing) liên tục và phục vụ các truy vấn Tìm kiếm (Search) có tần suất cực cao.

  • Phần cứng bắt buộc: CPU mạnh nhất, RAM lớn nhất, và ổ cứng SSD (NVMe) tốc độ cao nhất.

  • Vai trò Node: node.roles: [ data_hot ]

Tầng 2: Warm Tier (Kho lưu trữ ngắn hạn)

  • Nhiệm vụ: Lưu trữ dữ liệu đã "chốt sổ" (Không còn ghi mới nữa, tức là Index đã bị Rollover sang trạng thái Read-only). Tuy nhiên, dữ liệu này vẫn thường xuyên được dùng để vẽ Dashboard báo cáo (ví dụ: Log của tháng này).

  • Phần cứng lý tưởng: Không cần CPU quá mạnh. Có thể dùng ổ cứng HDD dung lượng lớn hoặc SSD giá rẻ.

  • Vai trò Node: node.roles: [ data_warm ]

Tầng 3: Cold Tier (Kho lưu trữ dài hạn)

  • Nhiệm vụ: Chứa dữ liệu hiếm khi được truy vấn (Ví dụ: Log của 3 tháng trước).

  • Bí kíp tiết kiệm: Ở tầng này, Elasticsearch không cần duy trì các Replica Shards (Bản sao dự phòng) trên ổ cứng Local nữa để tiết kiệm 50% dung lượng. Thay vào đó, nó dựa vào cơ chế Searchable Snapshots (Lưu bản backup lên S3/MinIO và có khả năng search trực tiếp trên file backup đó).

  • Phần cứng lý tưởng: Ổ cứng HDD siêu rẻ, dung lượng khổng lồ.

  • Vai trò Node: node.roles: [ data_cold ]

Tầng 4: Frozen Tier (Hầm băng ngàn năm)

  • Nhiệm vụ: Lưu trữ dữ liệu cho mục đích tuân thủ pháp luật/Audit (Ví dụ: Bắt buộc giữ log giao dịch trong 1 năm). Hầu như không bao giờ được search tới. Nếu có search, chấp nhận thời gian chờ lên tới vài phút.

  • Bí kíp "Vô cực": Các Node ở tầng Frozen KHÔNG CẦN LƯU DỮ LIỆU TRÊN Ổ CỨNG LOCAL. Toàn bộ dữ liệu nằm trên AWS S3 hoặc Google Cloud Storage. Node chỉ giữ một bộ Cache siêu nhỏ trên RAM/Disk để kéo dữ liệu từ S3 về khi có ai đó vô tình search trúng. Bạn có thể lưu hàng Petabyte dữ liệu với chi phí rẻ như cho.

  • Vai trò Node: node.roles: [ data_frozen ]

2. Cấu hình ILM để luân chuyển dữ liệu

Làm sao để Index afc_logs-000001 tự động "chuyển nhà" từ Hot Node sang Warm Node khi nó đầy?

Tuyệt vời thay, bạn không cần tự viết script di chuyển. Bạn chỉ cần sửa lại ILM Policy (ở Bài 41). Elasticsearch sẽ tự động ra lệnh chuyển Shard (Shard Allocation) ở background.

JSON

PUT _ilm/policy/afc_log_policy_tiered
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": { "max_size": "50gb" } // Vừa sinh ra sẽ nằm ở Hot. Đạt 50GB thì cắt file.
        }
      },
      "warm": {
        "min_age": "7d", // Chờ 7 ngày sau khi Rollover
        "actions": {
          "forcemerge": { "max_num_segments": 1 }, // Ép nén dữ liệu cho gọn nhẹ
          "allocate": { "require": { "data": "warm" } } // Đẩy tự động sang Warm Node
        }
      },
      "cold": {
        "min_age": "30d", // Sau 30 ngày
        "actions": {
          "searchable_snapshot": { "snapshot_repository": "my_s3_backup" }
        }
      },
      "delete": {
        "min_age": "365d", // Xóa vĩnh viễn sau 1 năm
        "actions": { "delete": {} }
      }
    }
  }
}
  1. Kiến trúc hệ thống khi Client gọi API Khi bạn đã phân tầng dữ liệu, API Backend của bạn có cần biết dữ liệu đang nằm ở tầng nào để gọi API cho đúng không? Câu trả lời là KHÔNG.

Bạn vẫn bắn câu query vào cụm Elasticsearch bình thường: GET afc_logs-*/_search.

Coordinating Node sẽ tự biết cách phân tán truy vấn:

Nếu bạn tìm log của hôm qua, nó sẽ chỉ fetch dữ liệu từ Hot Node (Trả về trong 10 mili-giây).

Nếu bạn tìm log của 6 tháng trước, nó sẽ gọi xuống Frozen Node. Lúc này, Frozen Node sẽ tốn vài giây (thậm chí chục giây) để kéo dữ liệu từ S3 về RAM và trả kết quả cho bạn.

Sự trong suốt (Transparent) này giúp Backend Developer hoàn toàn thảnh thơi, trong khi team DevOps/Infra lại có thể tối ưu hàng ngàn đô la chi phí server mỗi tháng.

Xuyên suốt bài học này, chúng ta đã nhắc nhiều đến S3 và Searchable Snapshots ở tầng Cold/Frozen. Nhưng làm thế nào để kết nối Elasticsearch với một dịch vụ Cloud Storage bên ngoài (như AWS S3 hoặc MinIO) để Backup dữ liệu? Nếu Data Center bị mất điện cháy nổ, làm sao để khôi phục lại cụm rỗng thành cụm hoàn chỉnh?


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í