Iceberg 1 — Open Table Format: vì sao lakehouse cần Iceberg

13 thg 7, 2026 4 lượt xem
#data-engineering
#lakehouse
#iceberg
#table-format
#open-format

Mở đầu: đống file Parquet không phải là một cái bảng

Rất nhiều đội dữ liệu bắt đầu hành trình lakehouse bằng một quyết định nghe rất hợp lý: đổ hết dữ liệu ra file Parquet (định dạng cột nén tốt, phổ biến) trên object storage như Amazon S3 hoặc HDFS, rồi để các engine như Spark, Trino, Hive đọc trực tiếp. Rẻ, mở, ai đọc cũng được. Đến khi hệ thống lớn lên, người ta mới nhận ra một sự thật phũ phàng: một đống file Parquet trong một thư mục không phải là một cái bảng đúng nghĩa. Nó chỉ là file. Không có ai đảm bảo tính toàn vẹn, không có giao dịch, không có lịch sử.

Bài này — mở màn cho series Apache Iceberg & Open Table Formats — trả lời câu hỏi gốc: tại sao cần một lớp gọi là open table format, và tại sao Apache Iceberg trở thành lựa chọn mặc định của ngành trong giai đoạn 2024–2025. Nếu bạn chưa nắm rõ sự khác nhau giữa data lake, warehouse và lakehouse, nên đọc trước Data Lake, Warehouse & Lakehouse.

Hive table cũ sai ở đâu

Trước Iceberg, cách phổ biến để biến file thành "bảng" là Hive table (Hive Metastore). Mô hình này rất đơn giản về ý tưởng: một bảng được định nghĩa bằng đường dẫn thư mục, và các partition (phân vùng) là các thư mục con. Ví dụ bảng transactions phân vùng theo ngày sẽ có cấu trúc s3://lake/transactions/dt=2026-07-13/part-0001.parquet. Metastore chỉ lưu: bảng nằm ở thư mục nào, có những partition nào. Còn "trong partition có file gì" thì để engine tự đi liệt kê thư mục lúc chạy query.

Cách làm "quản lý theo thư mục" này sinh ra hàng loạt vấn đề khi quy mô lớn:

  • Không có ACID. Không có khái niệm giao dịch. Nếu một job Spark đang ghi 500 file vào partition mà chết giữa chừng, bảng rơi vào trạng thái nửa vời: reader có thể đọc phải file dở dang. Hai job ghi đồng thời vào cùng partition có thể ghi đè hoặc làm hỏng lẫn nhau. Không có cách nào "commit toàn bộ hoặc không gì cả".
  • Liệt kê file chậm và tốn kém. Trên S3, việc "có những file nào trong thư mục này" phải thực hiện qua các lời gọi LIST — vốn chậm, bị giới hạn tần suất (rate limit) và tính phí. Một bảng vài chục nghìn partition khiến bước lập kế hoạch (planning) của query mất hàng phút chỉ để liệt kê, trước khi đọc được byte dữ liệu đầu tiên. S3 lại chỉ đảm bảo nhất quán cuối cùng (eventual consistency) trong lịch sử, khiến LIST đôi lúc trả về thiếu file vừa ghi.
  • Đổi schema đau đớn. Muốn đổi tên cột, đổi kiểu, chèn cột vào giữa? Hive nhận diện cột theo tên/vị trí, dễ dẫn tới đọc nhầm dữ liệu cũ. Nhiều thao tác đòi ghi lại toàn bộ bảng.
  • Đổi partition = viết lại toàn bảng. Chọn sai khóa phân vùng (ví dụ phân theo tháng nhưng thực tế cần theo ngày) thì cách duy nhất để sửa là tạo bảng mới và copy toàn bộ.
  • Không time travel. Không có ảnh chụp lịch sử. Xóa nhầm, ghi sai thì không có cách "quay lại phiên bản 5 phút trước". Kiểm toán ("bảng này lúc 9h sáng trông thế nào?") gần như bất khả thi.

Những vấn đề này không phải lỗi cấu hình — chúng là giới hạn kiến trúc của việc coi thư mục là bảng.

Open table format là gì

Open table format là một lớp metadata mở (open = chuẩn công khai, không khóa vào một nhà cung cấp) đặt trên các file dữ liệu (Parquet, ORC, Avro), biến "đống file" thành một bảng có giao dịch. Thay vì để engine đoán nội dung bảng bằng cách liệt kê thư mục, table format duy trì các file metadata mô tả chính xác bảng gồm những file dữ liệu nào, schema hiện tại là gì, phân vùng ra sao, và lịch sử thay đổi.

Điểm mấu chốt về mặt kiến trúc: table format tách storage khỏi engine. Dữ liệu và metadata nằm trên object storage rẻ tiền theo một chuẩn mở; bất kỳ engine nào hiểu chuẩn đó đều đọc/ghi được cùng một bảng — không bị nhốt vào một sản phẩm cụ thể.

Lớp metadata này mang lại đúng những thứ Hive table thiếu: giao dịch ACID, planning nhanh không cần LIST toàn bộ, đổi schema/partition an toàn, và lịch sử phiên bản để time travel.

Ba format lớn

Hiện có ba open table format chiếm lĩnh thị trường:

FormatNguồn gốcĐiểm mạnh nổi bật
Apache IcebergNetflix, nay là dự án top-level của Apache Software FoundationChuẩn thực sự mở & trung lập engine; hidden partitioning; schema/partition evolution mạnh; REST catalog
Delta LakeDatabricksGắn chặt hệ sinh thái Databricks/Spark; transaction log dạng file JSON; nay đã mở qua Delta Lake / UniForm
Apache HudiUberMạnh về upsertCDC (thay đổi bản ghi), tối ưu cho ingest gần thời gian thực

Cả ba đều giải cùng một bài toán cốt lõi (biến file thành bảng ACID) nhưng khác nhau về triết lý và hệ sinh thái. Chi tiết về Delta xem Delta Lake. Điểm khác biệt đáng nhớ:

  • Iceberg: thiết kế từ đầu để không phụ thuộc engine. Netflix xây Iceberg chính vì đau khổ với Hive table ở quy mô petabyte. Đặc sản là hidden partitioning — người dùng viết query theo cột logic, engine tự lo phân vùng.
  • Delta Lake: khởi nguồn gắn với Spark/Databricks, transaction log ghi dạng chuỗi file JSON trong thư mục _delta_log. Nhiều năm là "công dân hạng nhất" trên Databricks; gần đây đã mở hơn và có lớp tương thích để đọc như Iceberg.
  • Hudi: sinh ra cho bài toán CDC/upsert của Uber — cập nhật, xóa bản ghi hiệu quả với hai chế độ lưu trữ (copy-on-write và merge-on-read).

Vì sao Iceberg thắng thế 2024–2025

Không phải vì Iceberg "nhanh hơn" một cách tuyệt đối — cả ba format đều có kiến trúc tương tự. Iceberg vươn lên thành chuẩn ngành nhờ tính trung lậphệ sinh thái:

  1. Trung lập engine thật sự. Iceberg không do một nhà cung cấp thương mại kiểm soát. Kết quả: Spark, Trino, Flink, DuckDB, Snowflake, Google BigQuery, Amazon Athena/Redshift... đều đọc được bảng Iceberg. Bạn có thể ghi bằng Spark, đọc bằng Trino cho BI, xử lý streaming bằng Flink — trên cùng một bảng, không copy dữ liệu.
  2. REST Catalog. Iceberg định nghĩa một chuẩn REST catalog — API HTTP chung để mọi engine tra cứu metadata bảng. Điều này gỡ nút thắt lớn: trước đây mỗi engine cần một tích hợp catalog riêng. Xem sâu ở Catalogs & Engines.
  3. Được các ông lớn hậu thuẫn. Việc nhiều nhà cung cấp lớn (bao gồm cả Snowflake, và Databricks sau thương vụ mua Tabular — công ty do chính những người tạo ra Iceberg lập ra) đầu tư vào Iceberg tạo ra hiệu ứng chuẩn hóa: khi ai cũng hỗ trợ, chọn Iceberg là chọn phương án an toàn nhất về lâu dài, tránh khóa nhà cung cấp (vendor lock-in).

Các khái niệm cốt lõi

Bài này chỉ giới thiệu; các bài sau đào sâu từng phần. Nhưng nắm được năm khái niệm dưới đây là đủ để hiểu "tại sao Iceberg khác".

  • Snapshot (ảnh chụp). Mỗi lần ghi (commit) tạo ra một snapshot mới — trạng thái toàn bộ bảng tại một thời điểm, gồm danh sách chính xác các file dữ liệu hợp lệ. Bảng thực chất là một chuỗi snapshot bất biến. Đây là nền tảng cho mọi thứ còn lại. Kiến trúc metadata chi tiết ở Kiến trúc Iceberg.
  • ACID. Vì mỗi commit chỉ đơn giản là "trỏ bảng sang snapshot mới" một cách nguyên tử (atomic), reader luôn thấy một trạng thái nhất quán — không bao giờ đọc phải file ghi dở. Ghi đồng thời được giải quyết bằng optimistic concurrency (kiểm tra xung đột lúc commit).
  • Time travel (du hành thời gian). Vì snapshot cũ vẫn còn, bạn có thể query bảng "như nó vốn có" tại một snapshot hoặc mốc thời gian trong quá khứ — cực kỳ giá trị cho kiểm toán, debug, và tái lập kết quả. Xem ACID & Time Travel.
  • Schema & partition evolution. Iceberg gán ID duy nhất cho mỗi cột, nên đổi tên/thêm/bớt/đổi thứ tự cột là thao tác metadata an toàn, không ghi lại dữ liệu. Quan trọng hơn: đổi cách phân vùng cũng chỉ là thay đổi metadata — không phải viết lại toàn bảng như Hive. Chi tiết ở Evolution.
  • Hidden partitioning (phân vùng ẩn). Đây là "phép màu" của Iceberg. Với Hive, muốn dùng partition theo ngày, bạn phải tạo hẳn một cột dt và query phải nhớ lọc theo dt thì mới nhanh. Với Iceberg, bạn khai báo phân vùng là một hàm trên cột thật (ví dụ days(created_at)); người viết query chỉ cần lọc theo created_at bình thường, Iceberg tự động cắt bớt (prune) các partition không liên quan. Không còn cột dư thừa, không còn query chậm vì quên lọc đúng cột phân vùng.

Lakehouse: lake rẻ + tính năng warehouse

Ghép lại, ta hiểu vì sao lakehouse khả thi. Lakehouse = data lake (lưu file trên object storage: rẻ, mở, dung lượng vô hạn) + tính năng warehouse (ACID, schema chặt chẽ, giao dịch, hiệu năng query) — và chính table format là mảnh ghép làm cho phép cộng này thành sự thật. Không có table format, data lake mãi chỉ là bãi file; có nó, cùng một dữ liệu vừa rẻ như lake vừa đáng tin như warehouse.

Trong stack dữ liệu hiện đại, Iceberg đóng vai lớp lưu trữ bảng ở giữa: các engine tính toán như Apache Spark (ETL nặng, batch, ML) và Trino (truy vấn SQL tương tác cho BI) cùng đọc/ghi trên bảng Iceberg, thay vì mỗi công cụ ôm một bản sao dữ liệu riêng. Đây chính là ý nghĩa của "tách storage khỏi compute".

Ví dụ SQL: tạo và đọc bảng Iceberg

Các block SQL dưới đây là minh họa cú pháp Spark SQL / Trino trên bảng Iceberg. Chúng không chạy được trong sandbox PostgreSQL của Knowledge Base nên không được đánh dấu "chạy được".

Tạo một bảng Iceberg với hidden partitioning theo ngày (Spark SQL):

-- Minh họa Spark SQL — KHÔNG chạy trong sandbox
CREATE TABLE lake.core.transactions (
    txn_id      BIGINT,
    account_no  STRING,
    amount      DECIMAL(18,2),
    currency    STRING,
    created_at  TIMESTAMP
)
USING iceberg
PARTITIONED BY (days(created_at));   -- phân vùng ẩn theo ngày

Ghi dữ liệu và query bình thường — người dùng lọc theo created_at, không cần biết cột phân vùng:

-- Minh họa — Iceberg tự prune partition theo days(created_at)
SELECT currency, COUNT(*), SUM(amount)
FROM lake.core.transactions
WHERE created_at >= TIMESTAMP '2026-07-01 00:00:00'
GROUP BY currency;

Time travel — đọc bảng như tại một snapshot cũ (Trino):

-- Minh họa Trino — đọc phiên bản bảng tại một mốc quá khứ
SELECT COUNT(*)
FROM lake.core.transactions
FOR TIMESTAMP AS OF TIMESTAMP '2026-07-13 09:00:00 UTC';

Đổi cách phân vùng về sau mà không viết lại dữ liệu cũ:

-- Minh họa — partition evolution chỉ là thay đổi metadata
ALTER TABLE lake.core.transactions
ADD PARTITION FIELD hours(created_at);

Cú pháp cụ thể (mệnh đề, hàm phân vùng, cách gọi snapshot) khác nhau chút giữa Spark và Trino và giữa các phiên bản — luôn tra tài liệu engine đang dùng.

Use case thực tế

Bối cảnh (minh họa cho NCB). Giả sử NCB muốn xây một lakehouse tập trung cho dữ liệu giao dịch thẻ/chuyển khoản và log hệ thống, phục vụ ba nhóm khác nhau: đội rủi ro chạy batch nặng bằng Spark, đội phân tích/BI truy vấn SQL tương tác, và đội giám sát gian lận cần dữ liệu gần thời gian thực. Trước đây mỗi nhóm giữ một bản sao trong công cụ riêng, dẫn tới lệch số và tốn chi phí lưu trữ nhân nhiều lần.

Vì sao chọn Iceberg.

  • Đa engine trên một bảng. Cùng một bảng Iceberg trên object storage: Spark ghi ETL ban đêm, Trino phục vụ BI ban ngày, Flink hoặc job streaming nạp CDC gần thời gian thực — không nhân bản dữ liệu, mọi nhóm nhìn cùng một sự thật. Xem thêm Streaming & CDC.
  • ACID cho ghi đồng thời. Nhiều job cùng ghi vào bảng giao dịch mà không làm hỏng nhau; reader không bao giờ thấy dữ liệu nửa vời — điều kiện tiên quyết cho dữ liệu tài chính.
  • Kiểm toán bằng time travel. Khi có tranh chấp hoặc thanh tra, có thể tái lập bảng "đúng như 9h sáng ngày X", đáp ứng yêu cầu audit của ngân hàng.
  • Chi phí S3. Lưu trên object storage rẻ hơn nhiều so với giữ mọi thứ trong warehouse độc quyền tính phí theo dung lượng nén; đồng thời tránh vendor lock-in.

Số liệu ước lượng (chỉ để hình dung, không phải đo thực tế): một bảng giao dịch vài chục nghìn partition dạng Hive có thể mất hàng chục giây đến vài phút chỉ để planning do phải LIST S3; chuyển sang Iceberg, bước planning đọc metadata (manifest) thường xuống còn dưới vài giây vì danh sách file đã nằm sẵn trong metadata, kèm thống kê để cắt bớt file. Bỏ các bản sao trùng lặp giữa các nhóm có thể giảm đáng kể dung lượng lưu trữ. Lộ trình di chuyển thực tế của một ngân hàng xem Banking migration.

Ghi nhớ

  • Một đống file Parquet trong thư mục không phải một cái bảng: thiếu ACID, LIST S3 chậm, đổi schema/partition đau, không time-travel — đó là giới hạn kiến trúc của Hive table cũ.
  • Open table formatlớp metadata mở đặt trên file dữ liệu, biến file thành bảng có giao dịch và tách storage khỏi engine.
  • Ba format lớn: Apache Iceberg (chuẩn mở, đa engine, hidden partitioning — gốc từ Netflix, nay là dự án Apache), Delta Lake (gốc Databricks/Spark, nay mở hơn), Apache Hudi (mạnh upsert/CDC, gốc Uber).
  • Iceberg thắng thế 2024–2025 nhờ trung lập engine, REST catalog, và sự hậu thuẫn rộng của các nhà cung cấp lớn — chọn Iceberg là chống vendor lock-in.
  • Năm khái niệm cốt lõi: snapshot, ACID, time travel, schema/partition evolution, hidden partitioning — nền tảng cho các bài Kiến trúc, ACID & Time Travel, Evolution.
  • Lakehouse = data lake (rẻ, mở) + tính năng warehouse (ACID, schema), và table format chính là mảnh ghép làm điều đó khả thi; Iceberg là lớp bảng chung cho Spark, Trino và hơn thế.

Nguồn tham khảo

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.

13 thg 7, 2026 10

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.

13 thg 7, 2026 9

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.

13 thg 7, 2026 8

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.

13 thg 7, 2026 7

Cảm nhận của bạn

Bình luận

Bạn cần để viết bình luận.

Chưa có bình luận. Hãy là người đầu tiên chia sẻ!