0

Làm thế nào để thiết kế cấu trúc thư mục Partition chuẩn trên S3 cho Data Lake để tối ưu tốc độ đọc?

Thiết kế cấu trúc thư mục (Partitioning) trên S3 chính là "linh hồn" của Data Lake [cite: x]. Nếu cứ ném tất cả file Parquet vào chung một thư mục gốc, cái hồ dữ liệu (Data Lake) của bạn sẽ nhanh chóng biến thành "bãi lầy dữ liệu" (Data Swamp) — mỗi lần truy vấn sẽ quét toàn bộ dữ liệu, vừa chạy rùa bò vừa đốt tiền tỷ trên AWS [cite: x].

Để tối ưu hóa tốc độ đọc (nhờ cơ chế Partition Pruning - loại bỏ vách ngăn), dưới đây là tiêu chuẩn thiết kế cấu trúc thư mục S3 cấp độ Senior Data Engineer [cite: x].


1. Tiêu chuẩn vàng: Định dạng Hive-style Partitioning

Các engine phân tích dữ liệu như Athena, Spark, hay DuckDB đều ngầm hiểu và tự động nhận diện chuẩn thư mục của Apache Hive [cite: x]. Chuẩn này yêu cầu tên thư mục phải có định dạng tên_cột=giá_trị [cite: x].

Cấu trúc chuẩn trên S3 sẽ trông như thế này [cite: x]:

s3://bo-doi-datalake/production/user_events/
    ├── year=2026/
    │   ├── month=07/
    │   │   ├── day=01/
    │   │   │   ├── part-001.parquet
    │   │   │   └── part-002.parquet
    │   ├── month=08/
    │   │   ├── day=06/
    │   │   │   ├── part-001.parquet
    │   │   │   └── part-002.parquet

Khi bạn viết câu lệnh SQL: WHERE year='2026' AND month='08', Athena sẽ bỏ qua hoàn toàn các thư mục của tháng 7 hoặc các năm khác [cite: x]. Nó nhảy thẳng vào thư mục month=08 để đọc file [cite: x]. Khối lượng dữ liệu cần quét giảm từ hàng Terabyte xuống chỉ còn vài Gigabyte [cite: x].


2. 3 Nguyên tắc "Sống Còn" khi chọn cột để Partition

Không phải cột nào cũng mang ra làm thư mục được [cite: x]. Việc chọn sai cột sẽ phá nát hiệu năng hệ thống [cite: x].

Nguyên tắc 1: Cardinality (Độ phân tán dữ liệu) phải THẤP hoặc TRUNG BÌNH

  • Tuyệt đối không Partition theo cột có Cardinality cao (Ví dụ: user_id, email, order_id) [cite: x]. Nếu hệ thống có 10 triệu user, S3 sẽ tạo ra 10 triệu thư mục, mỗi thư mục chỉ chứa 1 file tí hon [cite: x]. Quá trình quét metadata của hàng triệu thư mục này sẽ khiến Athena treo cứng [cite: x].
  • Nên Partition theo cột có Cardinality thấp/trung bình (Ví dụ: Thời gian, country, event_type, department) [cite: x].

Nguyên tắc 2: Phân cấp theo tần suất truy vấn (Query Pattern)

Thứ tự các thư mục phải phản ánh đúng cách mà team Data Analyst thường xuyên filter (lọc) dữ liệu nhất [cite: x]. Thời gian hầu như luôn là bộ lọc số 1 [cite: x].

  • Cách xếp đúng: year=2026 / month=08 / country=VN / (Vì người ta thường lấy dữ liệu theo tháng trước, rồi mới chia theo quốc gia) [cite: x].
  • Cách xếp sai: country=VN / year=2026 / month=08 / (Trừ khi dự án của bạn có các team phân tích hoàn toàn độc lập theo từng quốc gia) [cite: x].

Nguyên tắc 3: Tránh thảm họa "Small File Problem" (Băm nát dữ liệu)

Các Big Data Engine xử lý file Parquet hiệu quả nhất khi dung lượng file nằm trong khoảng 128MB đến 1GB [cite: x].

  • Nếu bạn chia Partition quá sâu (Ví dụ: year/month/day/hour/minute), mỗi phút chỉ có vài MB dữ liệu sinh ra -> Hệ thống sẽ có hàng triệu file Parquet kích thước 1MB [cite: x]. Tốc độ đọc I/O sẽ tụt thê thảm [cite: x].
  • Giải pháp: Chỉ nên dừng lại ở cấp độ day (hoặc cùng lắm là hour nếu dữ liệu một ngày quá lớn) [cite: x]. Nếu file vẫn quá nhỏ, cần chạy các job định kỳ (như AWS Glue) để gộp các file nhỏ thành 1 file to (Compaction) [cite: x].

3. Bí kíp: Tách biệt năm, tháng, ngày hay dùng chung 1 chuỗi?

Có 2 trường phái chia Partition theo thời gian [cite: x]. Tùy vào đặc thù dự án mà bạn chọn cách phù hợp [cite: x]:

  • Trường hợp 1: Tách rời (Khuyên dùng cho dữ liệu khổng lồ)
    • Cấu trúc: .../year=2026/month=08/day=06/ [cite: x]
    • Ưu điểm: Dễ dàng lập lịch xóa dữ liệu cũ (Data Retention) theo năm, hoặc query tổng hợp toàn bộ 1 tháng mà không cần quét từng ngày [cite: x].
  • Trường hợp 2: Gộp chung kiểu Date (Dùng cho dữ liệu vừa phải)
    • Cấu trúc: .../dt=2026-08-06/ [cite: x]
    • Ưu điểm: Tiết kiệm độ sâu của thư mục [cite: x]. Query gọn gàng hơn: WHERE dt = '2026-08-06' [cite: x].

Chốt lại: Một cấu trúc Partition hoàn hảo là sự thỏa hiệp giữa việc giảm lượng dữ liệu bị quét (Scan ít đi) và đảm bảo kích thước file Parquet đủ lớn (128MB+) [cite: x].


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í