Iceberg 5 — Catalog & Engine: hệ sinh thái đa công cụ
Vì sao "một bảng, nhiều engine" lại là chuyện lớn
Trong thế giới data warehouse truyền thống, bảng và engine dính chặt vào nhau: bảng Oracle chỉ Oracle đọc, bảng Snowflake chỉ Snowflake truy vấn. Muốn cho công cụ khác dùng, bạn phải sao chép dữ liệu ra — tốn tiền lưu trữ, tốn pipeline đồng bộ, và mỗi bản sao là một nguồn lệch số liệu.
Apache Iceberg lật ngược mô hình đó. Dữ liệu (file Parquet/ORC) và metadata (manifest, snapshot) nằm trên object storage mở; bất kỳ engine nào hiểu đặc tả Iceberg đều đọc và ghi được cùng một bảng vật lý, không cần bản sao. Đây là trụ cột kỹ thuật của kiến trúc lakehouse: tách hẳn storage khỏi compute.
Nhưng để nhiều engine cùng thao tác an toàn trên một bảng, phải có một thành phần trọng tài trả lời câu hỏi "phiên bản metadata hiện hành của bảng này là file nào?" và đảm bảo hai engine ghi song song không giẫm chân nhau. Thành phần đó là catalog. Bài này mổ xẻ catalog và bức tranh engine — hai mảnh ghép biến Iceberg thành một chuẩn mở đa công cụ.
Catalog là gì và làm gì
Nhắc lại từ bài kiến trúc: mỗi bảng Iceberg có một file metadata.json ở đỉnh, mô tả schema, partition spec và danh sách snapshot. Vấn đề: khi ghi, Iceberg tạo file metadata.json mới (v2, v3…) chứ không sửa file cũ. Vậy làm sao engine đọc biết đâu là bản mới nhất?
Catalog chính là sổ đăng ký ánh xạ tên bảng → đường dẫn metadata.json hiện hành. Nó giữ một con trỏ, ví dụ retail.transactions → s3://.../metadata/00007-....metadata.json. Hai vai trò cốt lõi:
- Phân giải tên bảng: engine hỏi catalog "bảng
retail.transactionsở đâu?", catalog trả về đường dẫn metadata hiện hành để engine bắt đầu đọc. - Commit nguyên tử: khi một writer muốn công bố snapshot mới, nó yêu cầu catalog đổi con trỏ từ v7 sang v8 bằng phép compare-and-swap — "chỉ đổi nếu con trỏ hiện đang là v7". Đây là mắt xích khóa ACID (xem bài 3): nhờ catalog đảm bảo tính nguyên tử của bước đổi con trỏ, hai job ghi song song không thể cùng công bố và làm hỏng nhau.
Lưu ý sơ đồ: engine nói chuyện với catalog để biết đọc/ghi file nào và commit, nhưng luồng data file thật sự đi thẳng giữa engine và object storage — catalog không nằm trên đường dữ liệu nặng, nó chỉ điều phối metadata nên rất nhẹ.
Các loại catalog
Iceberg định nghĩa một interface catalog, và có nhiều bản cài đặt. Chọn loại nào ảnh hưởng lớn tới khả năng liên thông và vận hành.
REST catalog — chuẩn mở đang thắng thế
REST catalog không phải một sản phẩm cụ thể mà là một đặc tả API HTTP mở (Iceberg REST Catalog spec). Bất kỳ dịch vụ nào cài đúng spec đều thành catalog; engine chỉ cần một client REST chung, không cần driver riêng cho từng backend. Đây là bước ngoặt: trước REST catalog, mỗi engine phải nhúng logic riêng để nói chuyện với Hive, Glue, JDBC… Với REST, engine nói một ngôn ngữ duy nhất, còn phía sau server tự lo lưu trữ metadata (có thể là Postgres, DynamoDB, hay tầng nào tùy).
Ưu điểm quyết định:
- Interoperability: cùng một endpoint phục vụ Spark, Trino, Flink, PyIceberg… đồng nhất.
- Server-side logic: commit, kiểm xung đột, phân quyền, cấp credential vending (server phát token tạm để engine truy cập storage) tập trung ở server thay vì rải trong client.
- Không lệ thuộc client version: nâng cấp logic ở server, client cũ vẫn chạy.
Các bản cài REST catalog phổ biến: Apache Polaris, Lakekeeper, Unity Catalog (chế độ Iceberg REST), Tabular (nay thuộc Databricks), Gravitino. Xu hướng ngành 2024–2025 rõ ràng nghiêng về REST catalog làm mẫu số chung.
Hive Metastore (HMS)
Catalog "đời đầu" của thế giới Hadoop, dùng một database quan hệ (thường MySQL/Postgres) lưu metadata bảng qua giao thức Thrift. Rất phổ biến vì hạ tầng Hadoop cũ đã có sẵn HMS. Nhược điểm: giao thức Thrift nặng nề, khó phân quyền mịn, và mỗi engine cần thư viện client HMS. Nhiều tổ chức đang dần thay HMS bằng REST catalog.
AWS Glue Data Catalog
Catalog managed của AWS, tích hợp sẵn với Athena, EMR, Redshift Spectrum. Nếu toàn bộ nền tảng nằm trên AWS, Glue tiện vì không phải tự vận hành, và gắn liền IAM. Đổi lại: khóa vào hệ sinh thái AWS, và một số engine ngoài AWS hỗ trợ Glue hạn chế hơn REST.
JDBC catalog
Đơn giản nhất: lưu con trỏ bảng trong một bảng của database JDBC bất kỳ (Postgres/MySQL). Nhẹ, dễ dựng cho môi trường nhỏ hoặc dev/test. Nhược: không có tầng phân quyền/credential vending, tính năng nghèo, khó scale vận hành.
Nessie — catalog kiểu Git
Project Nessie đưa mô hình branch/tag như Git vào catalog: bạn tạo branch để làm ETL thử nghiệm, chạy nhiều bảng, kiểm thử, rồi merge vào main như một transaction đa bảng. Time travel không chỉ theo snapshot của một bảng mà theo commit của cả catalog. Rất mạnh cho quy trình write-audit-publish và thí nghiệm dữ liệu, nhưng thêm một khái niệm vận hành mới cần đội ngũ làm chủ.
Apache Polaris
Apache Polaris là REST catalog mã nguồn mở do Snowflake khởi xướng rồi hiến cho Apache. Nó cài đầy đủ Iceberg REST spec, thêm quản trị (role-based access control), credential vending, và được thiết kế để nhiều engine — kể cả Snowflake — dùng chung một catalog. Là ứng viên nặng ký cho vai trò catalog trung lập, không khóa vendor.
Unity Catalog
Catalog của Databricks, ban đầu gắn với Delta Lake nhưng nay đã hỗ trợ Iceberg và mở endpoint Iceberg REST, đồng thời được mở nguồn (Unity Catalog OSS). Cho phép engine ngoài Databricks đọc bảng qua giao thức Iceberg. Mạnh về governance (lineage, phân quyền, audit) nhưng trải nghiệm tốt nhất vẫn trong hệ Databricks.
So sánh nhanh
| Catalog | Chuẩn mở | Phân quyền mịn | Branch/tag | Khi nào chọn |
|---|---|---|---|---|
| REST (spec) | ✔ chuẩn API | tùy bản cài | tùy bản cài | Mặc định cho hạ tầng mới, đa engine |
| Hive Metastore | Một phần | Yếu | ✘ | Đã có sẵn Hadoop/HMS |
| AWS Glue | AWS | IAM | ✘ | All-in AWS, ngại tự vận hành |
| JDBC | ✔ đơn giản | ✘ | ✘ | Dev/test, quy mô nhỏ |
| Nessie | ✔ | Có | ✔ (Git-like) | Cần thí nghiệm/WAP đa bảng |
| Polaris | ✔ REST | RBAC | ✘ | Catalog trung lập, có Snowflake |
| Unity Catalog | ✔ REST (Iceberg) | Mạnh | ✘ | Nền tảng Databricks + mở ra ngoài |
Quy tắc ngón tay cái: hạ tầng mới → REST catalog (Polaris, Lakekeeper, hoặc Unity nếu đã dùng Databricks); AWS thuần thì Glue; cần branch/tag đa bảng thì Nessie. Tránh cột chặt vào HMS cho dự án dài hạn.
Các engine đọc/ghi Iceberg
Điểm hấp dẫn: mỗi engine giỏi một việc, và tất cả dùng chung bảng.
- Spark — hỗ trợ Iceberg đầy đủ nhất (thường là engine tham chiếu). Ghi batch quy mô lớn,
MERGE INTO, quản lý DDL, và toàn bộ thao tác maintenance (compaction, expire snapshot, rewrite manifest — xem bài 6). Là lựa chọn cho ETL nặng và ML feature engineering. - Trino / Presto — engine MPP cho truy vấn tương tác độ trễ thấp, join liên nguồn (federated). Lý tưởng cho analyst chạy ad-hoc và làm backend cho BI. Ghi được nhưng thường dùng chủ yếu để đọc.
- Flink — engine streaming, ghi liên tục vào Iceberg từ Kafka/CDC với exactly-once. Là xương sống cho ingest thời gian thực và streaming/CDC vào Iceberg.
- DuckDB — engine phân tích in-process siêu nhẹ, đọc Iceberg ngay trên laptop/notebook qua extension. Tuyệt cho khám phá dữ liệu và test cục bộ, không cần cụm.
- Snowflake — hỗ trợ Iceberg table (managed hoặc external), cho phép warehouse thương mại truy vấn thẳng bảng trên lake của bạn.
- BigQuery — qua BigLake/BigQuery tables for Iceberg, đọc (và ngày càng ghi được) bảng Iceberg trên GCS, hòa vào SQL của BigQuery.
- ClickHouse — có
Icebergtable engine để đọc bảng Iceberg, ghép sức mạnh truy vấn cực nhanh của ClickHouse vào dữ liệu lake.
Điểm chung: không engine nào "sở hữu" dữ liệu. Bảng nằm trên storage của bạn; engine chỉ là compute gắn vào rồi tháo ra tùy nhu cầu.
"One copy, many engines" trong thực tế
Đây là mô hình vận hành mà Iceberg cho phép:
Một bản dữ liệu duy nhất phục vụ mọi tải: Flink ghi streaming, Spark ghi batch và dọn dẹp, Trino phục vụ analyst và BI, ML đọc feature, warehouse ngoài đọc để làm báo cáo. Lợi ích:
- Không nhân bản dữ liệu: bớt chi phí lưu trữ và xóa hẳn lớp pipeline sao chép/đồng bộ — vốn là nguồn lỗi và lệch số kinh điển.
- Một sự thật (single source of truth): mọi engine thấy cùng snapshot, cùng con số. Analyst và mô hình ML không còn tranh cãi "số của ai đúng".
- Chống vendor lock-in: đổi engine không phải di cư dữ liệu. Không hài lòng warehouse A, cắm engine B vào cùng bảng.
- Chọn công cụ đúng việc: dùng thế mạnh từng engine mà không tạo silo.
Cạm bẫy interoperability
"Nhiều engine cùng bảng" nghe đẹp, nhưng có những chỗ dễ vấp — cần biết trước:
- Chênh lệch hỗ trợ tính năng: các engine không ngang nhau về format version và tính năng. Ví dụ row-level delete (merge-on-read) với positional/equality delete được Spark/Flink ghi tốt, nhưng một engine đọc cũ hơn có thể chưa áp dụng đúng delete file → trả ra dòng đáng lẽ đã xóa. Hidden partitioning (xem bài evolution) cũng cần engine hiểu partition transform. Luôn kiểm ma trận hỗ trợ theo format version (v1 vs v2/v3) trước khi cho một engine tham gia.
- Catalog credential và permission: mỗi engine phải cấu hình đúng để cùng nói chuyện một catalog và có quyền đọc storage phía sau. Với REST catalog + credential vending, catalog phát token tạm cho engine — tiện nhưng cần nhất quán cấu hình. Sai IAM/role là lỗi "chạy được ở Spark, fail ở Trino" hay gặp nhất.
- Đồng bộ commit và ghi đồng thời: nhiều engine cùng ghi một bảng dựa trên optimistic concurrency; nếu hai bên đụng cùng file, một bên phải retry. Đồng thời, một số engine cache metadata → sau khi engine A commit, engine B có thể còn thấy snapshot cũ đến khi refresh. Với bảng ghi nóng, cần hiểu độ trễ nhìn thấy này.
- Chỉ một cây ghi cho một phạm vi: thực hành tốt là để một engine "chủ" ghi mỗi phân vùng/bảng, các engine khác chủ yếu đọc, tránh ganh commit không cần thiết.
- Maintenance là của Spark/engine biết làm: compaction và expire snapshot nên do một engine đảm nhiệm (thường Spark), tránh nhiều nơi cùng dọn.
Ví dụ: một REST catalog, đọc cùng bảng từ Spark và Trino
Minh họa (không phải SQL sandbox) cấu hình một REST catalog dùng chung, rồi cả Spark lẫn Trino đọc cùng bảng warehouse.retail.transactions.
Spark (spark-defaults / khi tạo session) — trỏ vào REST catalog:
spark.sql.catalog.wh = org.apache.iceberg.spark.SparkCatalog
spark.sql.catalog.wh.type = rest
spark.sql.catalog.wh.uri = https://catalog.mybank.internal/api/catalog
spark.sql.catalog.wh.warehouse = s3://lakehouse/wh
spark.sql.catalog.wh.io-impl = org.apache.iceberg.aws.s3.S3FileIO
spark.sql.extensions = org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions
-- minh hoạ (Spark SQL) — KHÔNG phải sandbox
SELECT kind, COUNT(*) FROM wh.retail.transactions GROUP BY kind;
Trino (etc/catalog/wh.properties) — cùng URI, cùng warehouse:
connector.name=iceberg
iceberg.catalog.type=rest
iceberg.rest-catalog.uri=https://catalog.mybank.internal/api/catalog
iceberg.rest-catalog.warehouse=s3://lakehouse/wh
-- minh hoạ (Trino) — cùng bảng vật lý Spark vừa đọc
SELECT date_trunc('day', created_at) d, SUM(amount)
FROM wh.retail.transactions
WHERE created_at >= TIMESTAMP '2026-07-01 00:00:00'
GROUP BY 1 ORDER BY 1;
Cả hai cấu hình trỏ về cùng uri và cùng warehouse → cùng con trỏ metadata → cùng bảng, cùng snapshot. Spark ghi xong commit, Trino refresh là thấy ngay dữ liệu mới — không có bước copy nào ở giữa. Đó là toàn bộ tinh thần "một bảng, nhiều engine".
Use case thực tế
Bối cảnh NCB. Đội dữ liệu cần một bảng giao dịch thẻ/tài khoản vừa phục vụ cảnh báo gần thời gian thực, vừa cho analyst truy vấn, vừa nuôi mô hình rủi ro — mà không muốn ba bản sao ở ba hệ thống. Giải pháp: một bảng Iceberg core.txn_events trên S3, một REST catalog (Polaris tự vận hành) làm trọng tài, ba engine cắm vào.
Kiến trúc (số liệu ước lượng minh họa):
- Flink ghi streaming: đọc CDC từ core banking qua Kafka, ghi vào
core.txn_eventsvới commit mỗi ~30 giây. Lưu lượng ước tính ~3–5 triệu bản ghi/ngày, độ trễ end-to-end vài chục giây. Team fraud dùng chính bảng này để chấm điểm cảnh báo. - Trino cho analyst: ~40 analyst nghiệp vụ chạy ad-hoc và dashboard (đối soát, hành vi giao dịch) trực tiếp trên bảng, không cần chờ ETL sao chép sang mart. Truy vấn theo ngày trả về trong vài giây nhờ hidden partition theo
day(created_at). - Spark cho batch & ML: job đêm tính đặc trưng (feature) 90 ngày cho mô hình rủi ro, đọc cùng bảng; đồng thời Spark đảm nhiệm maintenance — compaction file nhỏ do Flink sinh ra và expire snapshot cũ, giữ hiệu năng đọc.
- Phân quyền: REST catalog cấp role — Flink có quyền ghi, analyst chỉ đọc (và bị lọc cột nhạy cảm ở tầng view/policy), Spark ML đọc + ghi bảng feature riêng. Credential vending phát token S3 tạm theo phiên, không rải access key cứng trong cấu hình engine.
Kết quả kỳ vọng: bỏ được ~2 pipeline sao chép sang warehouse/mart (giảm điểm lỗi và lệch số), một sự thật cho cả fraud, analyst lẫn ML, và khả năng thay/bổ sung engine (ví dụ cắm thêm DuckDB cho phân tích cục bộ hoặc ClickHouse cho dashboard nóng) mà không đụng tới dữ liệu. Rủi ro cần quản: kỷ luật để chỉ Flink ghi luồng nóng, Spark lo maintenance, và kiểm ma trận tính năng (format v2 với merge-on-read) trước khi cho engine mới đọc, tránh đọc sai delete file.
Ghi nhớ
- Catalog giữ ánh xạ tên bảng → metadata.json hiện hành và thực hiện commit nguyên tử (compare-and-swap) — mắt xích khóa ACID cho phép nhiều engine ghi an toàn.
- REST catalog là một đặc tả API mở, không phải sản phẩm; cho phép mọi engine nói chung một ngôn ngữ. Xu hướng ngành nghiêng hẳn về REST (Polaris, Unity Catalog OSS, Lakekeeper…).
- Các loại catalog: REST (mặc định cho hạ tầng mới), HMS (kế thừa Hadoop), Glue (AWS), JDBC (dev/nhỏ), Nessie (branch/tag kiểu Git), Polaris (REST mở của Snowflake), Unity Catalog (Databricks, đã hỗ trợ Iceberg).
- Engine mạnh riêng: Spark đầy đủ nhất (ETL/ML/maintenance), Trino truy vấn tương tác, Flink streaming, DuckDB nhẹ cục bộ; warehouse ngoài Snowflake/BigQuery/ClickHouse đọc thẳng bảng.
- One copy, many engines: tách storage khỏi compute → không nhân bản, một sự thật, chống vendor lock-in, chọn công cụ đúng việc.
- Cạm bẫy: chênh lệch hỗ trợ tính năng (row-level delete, hidden partition) theo format version; cấu hình catalog credential/permission nhất quán; độ trễ nhìn thấy commit do cache; nên có một engine "chủ ghi" và một engine lo maintenance.
- Cùng
uri+ cùngwarehouseở Spark và Trino = cùng bảng vật lý, cùng snapshot, không có bước copy.
Nguồn tham khảo
- Apache Iceberg Documentation — Catalogs (REST, Hive, Glue, JDBC, Nessie): https://iceberg.apache.org/docs/latest/
- Apache Iceberg — REST Catalog Open API Specification: https://github.com/apache/iceberg/blob/main/open-api/rest-catalog-open-api.yaml
- Apache Iceberg — Spark integration (configuration & procedures): https://iceberg.apache.org/docs/latest/spark-configuration/
- Trino Documentation — Iceberg connector: https://trino.io/docs/current/connector/iceberg.html
- Apache Flink — Iceberg connector (flink-getting-started): https://iceberg.apache.org/docs/latest/flink/
- Apache Polaris — REST catalog cho Iceberg: https://polaris.apache.org/
- Project Nessie — Git-like data catalog: https://projectnessie.org/
- AWS Glue Data Catalog — Documentation: https://docs.aws.amazon.com/glue/latest/dg/catalog-and-crawler.html
Bài viết liên quan
So sánh các định dạng dữ liệu (CSV, JSON, XML, Avro, Parquet, ORC) và lý do lưu theo cột nhanh hơn cho phân tích. Bài đi sâu vào row vs columnar storage, nén (Snappy/gzip/zstd), schema evolution, OLTP vs OLAP, object storage và partitioning để tối ưu chi phí lẫn tốc độ truy vấn.
Data Engineering là ngành xây dựng và vận hành hệ thống biến dữ liệu thô thành dữ liệu sạch, tin cậy, sẵn sàng cho phân tích và AI. Bài giới thiệu vai trò Data Engineer trong vòng đời dữ liệu (nguồn → ingestion → storage → transformation → serving), phân biệt với Analyst/Scientist/ML Engineer, bức tranh hệ sinh thái công cụ và bài toán đưa dữ liệu core banking sang kho phân tích.
Stream processing là gì, khác biệt batch vs stream (bounded/unbounded), micro-batch (Spark) vs true streaming, Apache Flink là gì và định vị so với Spark Structured Streaming và Kafka Streams. Kiến trúc runtime JobManager/TaskManager, các tầng API, triết lý streaming-first và bối cảnh phát hiện gian lận ngân hàng.
Vì sao một máy không đủ và cần xử lý phân tán: từ MapReduce, Hadoop/HDFS đến Apache Spark in-memory. Kiến trúc driver–executor–cluster manager, các mức trừu tượng RDD/DataFrame/Dataset, cơ chế lazy evaluation với DAG, và vì sao shuffle (wide dependency) là phần tốn kém nhất. Kèm PySpark, Spark SQL và các kỹ thuật tối ưu (partition, broadcast join, cache, chống skew) cùng khi nào KHÔNG nên dùng Spark.
Cảm nhận của bạn
Bình luận
Chưa có bình luận. Hãy là người đầu tiên chia sẻ!