Cấu hình chiến lược Partitioning cho Iceberg
Trong Iceberg, partitioning là cơ chế chia nhỏ dữ liệu vật lý dựa trên các giá trị của cột để giảm lượng dữ liệu cần quét (pruning) khi thực hiện truy vấn.
Chúng ta sẽ áp dụng chiến lược Partition Transform bao gồm Identity (giữ nguyên giá trị), Bucket (hash để cân bằng) và Range (phân vùng theo khoảng) tùy theo đặc thù dữ liệu.
Đầu tiên, hãy xác định lại cấu trúc bảng customer_orders với các partition transform tối ưu cho truy vấn theo ngày và khu vực.
Sử dụng lệnh ALTER TABLE để thêm partition spec mới. Lưu ý: Iceberg cho phép nhiều partition spec, nhưng mỗi lần ghi dữ liệu mới sẽ chọn spec phù hợp hoặc spec mặc định.
ALTER TABLE customer_orders ADD PARTITION SPEC (
bucket(4, customer_id),
trunc(4, order_date),
identity(customer_region)
);
Kết quả mong đợi: Hệ thống trả về thông báo "OK" và bảng đã có một partition spec mới với ID tăng dần.
Verify cấu hình Partition
Thực hiện lệnh sau để kiểm tra các partition spec hiện có của bảng.
DESCRIBE TABLE customer_orders PARTITION SPEC;
Kết quả hiển thị danh sách các partition spec, trong đó spec mới nhất (có ID lớn nhất) sẽ là spec mặc định cho các ghi mới.
Triển khai Z-Ordering Index để tăng tốc lọc dữ liệu
Partitioning truyền thống gặp hạn chế khi lọc theo nhiều cột cùng lúc hoặc lọc các giá trị không nằm trong partition key. Z-Ordering giúp giải quyết vấn đề này bằng cách sắp xếp dữ liệu trong file Parquet theo một "không gian" đa chiều.
Z-Ordering sử dụng thuật toán Hilbert Curve để ánh xạ các chiều dữ liệu (ví dụ: order_date và amount) vào một chiều duy nhất, đảm bảo các bản ghi có giá trị gần nhau trong không gian đa chiều sẽ nằm gần nhau trong file vật lý.
Để kích hoạt Z-Ordering, bạn cần cấu hình write.zorder trong session của Trino hoặc Spark khi ghi dữ liệu, hoặc thực hiện ALTER TABLE để áp dụng lên toàn bộ dữ liệu hiện có.
Áp dụng Z-Ordering lên các cột order_date và amount để tối ưu các truy vấn kết hợp lọc theo ngày và số tiền.
ALTER TABLE customer_orders SET TBLPROPERTIES ('write.zorder' = 'order_date, amount');
Kết quả mong đợi: Iceberg ghi nhận thuộc tính mới vào metadata của bảng. Các ghi dữ liệu mới sẽ tự động được sắp xếp theo Z-Ordering.
Thực thi Z-Ordering trên dữ liệu cũ
Thuộc tính write.zorder chỉ ảnh hưởng đến dữ liệu mới. Để sắp xếp lại dữ liệu cũ, bạn cần chạy lệnh REWRITE DATA.
REWRITE DATA customer_orders WHERE '2023-01-01'
Kết quả mong đợi: Lệnh sẽ đọc lại các file cũ, sắp xếp lại nội dung theo Z-Ordering và ghi vào các file mới, sau đó cập nhật metadata.
Thực hiện Optimize: Rewrite Files và Compaction
Khi dữ liệu được ghi vào Iceberg qua nhiều lần ETL nhỏ, số lượng file Parquet sẽ tăng lên (file explosion), gây áp lực lên hệ thống file và làm chậm truy vấn. Chúng ta cần thực hiện Compaction để gộp các file nhỏ thành file lớn hơn.
Hãy thực hiện REWRITE DATA với chiến lược size để gộp các file có kích thước nhỏ hơn ngưỡng mong muốn (ví dụ: 1GB) thành các file lớn hơn.
REWRITE DATA customer_orders WHERE true;
Lệnh này sẽ quét toàn bộ bảng và gộp các file nhỏ. Kết quả mong đợi là số lượng file giảm đáng kể, trong khi tổng kích thước dữ liệu vẫn giữ nguyên.
Cấu hình chính sách Optimize tự động
Để tự động hóa quá trình này, hãy cấu hình optimize trong catalog hoặc session. Dưới đây là cấu hình cho Trino để kích hoạt Compact tự động khi ghi dữ liệu.
Tạo file cấu hình trino.properties (hoặc cập nhật trong catalog/iceberg.properties) với các tham số sau:
cat > /etc/trino/catalog/iceberg.properties
Khởi động lại Trino hoặc áp dụng cấu hình để các ghi mới tuân thủ kích thước file tối ưu.
Đo lường hiệu năng trước và sau tối ưu
Để đánh giá hiệu quả của Partitioning và Z-Ordering, chúng ta cần so sánh thời gian thực thi và lượng dữ liệu quét (Data Scanned) của cùng một truy vấn trước và sau khi tối ưu.
Thực hiện truy vấn mẫu lọc theo ngày và số tiền trước khi tối ưu (nếu dữ liệu chưa được rewrite).
EXPLAIN ANALYZE SELECT COUNT(*) FROM customer_orders WHERE order_date >= '2023-06-01' AND amount > 1000;
Quan sát phần Statistics trong kết quả EXPLAIN, chú ý đến Rows read (số hàng đọc) và Elapsed (thời gian). Ghi lại các giá trị này.
Sau khi hoàn thành các bước REWRITE DATA và Z-Ordering, thực hiện lại cùng một lệnh truy vấn.
EXPLAIN ANALYZE SELECT COUNT(*) FROM customer_orders WHERE order_date >= '2023-06-01' AND amount > 1000;
So sánh kết quả:
- Rows read: Cần giảm đáng kể nhờ Z-Ordering và Partition pruning.
- Elapsed time: Thời gian thực thi phải ngắn hơn.
- Files scanned: Số lượng file Parquet cần đọc phải giảm do Compaction.
Verify bằng metadata Iceberg
Để kiểm tra số lượng file và kích thước trung bình, truy vấn vào bảng hệ thống system.information_schema.files của Iceberg.
SELECT COUNT(*) as total_files, AVG(file_size_in_bytes) as avg_file_size FROM system.information_schema.files WHERE table_name = 'customer_orders';
Kết quả mong đợi: Sau khi optimize, total_files giảm và avg_file_size tăng lên gần ngưỡng mục tiêu (1GB) đã cấu hình.
Điều hướng series:
Mục lục: Series: Xây dựng nền tảng Data Fabric hiện đại với Apache Iceberg, Trino và Kubernetes
« Phần 4: Quản lý dữ liệu: Ghi, đọc và cập nhật dữ liệu Iceberg
Phần 5: Tối ưu hóa hiệu năng với Partitioning và Indexing trong Iceberg »