Apache XTable 介绍与选型指南
Apache XTable 0.4 的定位、核心架构(元数据互转不改数据文件)、支持的表格式矩阵、增量与全量同步机制及同类方案选型对比
Apache XTable 介绍与选型指南
目标:讲清 Apache XTable 是什么、解决什么问题、由哪些组件构成、支持哪些表格式互转,以及在 2026 年当前版本(0.4.0-incubating)下的同类方案选型对比。本文结论均已在 Ubuntu 22.04 + OpenJDK 17 + Spark 3.4.4 环境安装 Apache XTable 0.4.0-incubating 并完成 Hudi/Iceberg/Delta/Parquet 四种格式的互转实测验证(安装过程见《Ubuntu 22.04 安装 Apache XTable 0.4 指南》)。
一、环境信息
本文结论基于以下实测环境:
- 操作系统:Ubuntu 22.04(x86_64)
- Java:OpenJDK 17.0.20.1(运行环境);源码编译需 OpenJDK 11(实测 JDK 17 编译会因 lombok delombok 步骤失败,见安装指南常见问题)
- 计算引擎:Apache Spark 3.4.4(Scala 2.12.17)
- 组件版本:Apache XTable 0.4.0-incubating(Apache 孵化器项目,第四个官方版本)
- 关键制品:
xtable-spark-runtime_2.12-0.4.0-incubating.jar(约 4.3 MB,Maven Central 提供) - 依赖版本(与 XTable 0.4.0 构建矩阵一致):Apache Hudi 0.14.0、Apache Iceberg 1.9.2、Delta Lake 2.4.0(Spark 3.4 路径)、Apache Avro 1.12.0、Apache Parquet 1.15.2
- 官方站点:https://xtable.apache.org
二、软件概述
Apache XTable™(Incubating)是一个开源的表格式(Table Format)互操作性工具,前身是 OneTable 项目,捐赠给 Apache 软件基金会后进入孵化器。它解决的核心问题是:数据湖中同一份数据文件,往往需要同时被 Hudi、Iceberg、Delta Lake 三种表格式生态的引擎和平台读取,而主流引擎各自只"原生"写一种格式。
XTable 的做法是只同步元数据,不改写数据文件:读取源表(如 Hudi)的 schema、提交历史、分区、列统计(column statistics),然后在同一份数据文件旁边生成目标格式(如 Iceberg、Delta)所需的全部元数据文件,使目标格式的查询引擎无需拷贝、无需重写数据即可直接查询这份数据。
💡 技术拓展:为什么"只转元数据"可行——三种表格式的数据底层都是 Parquet/ORC 等列式文件,差异全在元数据层(Hudi 的时间线
.hoodie/、Iceberg 的metadata/清单、Delta 的_delta_log/事务日志)。只要按目标格式的语义补齐元数据(数据文件清单、统计信息、快照版本),引擎读取时并不会区分文件最初是谁写的。这也是 XTable 与传统"ETL 重写一份数据"方案的本质区别:同步一次的成本是 MB 级元数据,而非 TB 级数据拷贝。
三、核心架构
3.1 同步流水线
XTable 的同步过程是一条「源解析 → 内部统一模型 → 目标生成」的流水线:
源表(HUDI/ICEBERG/DELTA/PAIMON/PARQUET)
│ ① ConversionSource:解析源格式元数据
▼
内部统一模型(InternalTable:schema / 分区 / InternalDataFile + columnStats / 提交历史)
│ ② ConversionTarget:按目标格式语义生成元数据
▼
目标表元数据(.hoodie/ 或 metadata/ 或 _delta_log/,与源数据文件同目录共存)
关键点:
- 数据文件零拷贝:同步只新增元数据文件,数据 Parquet 文件原地不动,多个格式共享同一批物理文件。
- 增量同步:XTable 在目标格式元数据中记录水位(如 Delta 事务日志中的
XTABLE_METADATA.lastInstantSynced),下次同步只处理源表新增的提交;增量不可行时自动回退全量快照同步。 - 元数据维护:同步过程中顺带做目标格式的元数据维护(Hudi 清理未引用文件、Iceberg 过期快照、Delta 事务日志保留期控制),避免目标元数据无限膨胀。
3.2 两种同步能力
| 能力 | 说明 | 入口 |
|---|---|---|
| TableFormatSync | 表格式元数据互转(本文主线) | xtable-spark-runtime 的 XTableSparkSync(spark-submit)或作业内 XTableSyncService API |
| CatalogSync | 把同步出的目标表自动注册到外部目录(HMS、AWS Glue,更多目录陆续支持) | Catalog 同步配置(源码 xtable-hive-metastore、xtable-aws 模块) |
3.3 可运行形态(0.4.0 实测)
0.4.0 版本提供三种使用形态:
- 独立 spark-submit 作业:
spark-submit --class org.apache.xtable.spark.XTableSparkSync xtable-spark-runtime_2.12-0.4.0-incubating.jar --basepath /opt/data/hudi-dataset/people --sourceformat HUDI --targets ICEBERG,DELTA(0.4.0 新增,本文实测主线)。 - 嵌入既有 Spark 作业:在写入代码后调用
XTableSyncService.sync(TableSyncSpec, hadoopConf),写完即同步。 - REST 服务:源码
xtable-service模块(Quarkus 实现),以 HTTP 服务形式提交转换请求,适合平台化集成。
⚠️ 实测注意:官方下载页提到可从 release tag 构建可运行的
xtable-utilities_2.12-<version>-bundled.jar(java -jar方式),该模块只存在于 main 分支(0.5.0-SNAPSHOT),0.4.0-incubating 源码中没有xtable-utilities模块(实测解包验证),按官方下载页的命令构建会报POM file xtable-utilities/pom.xml does not exist。0.4.0 的可运行入口是上表三种形态。
四、支持的表格式矩阵
以下矩阵综合官方文档与本次实测(✅ 表示实测通过并完成目标表读回验证):
| 源格式 ↓ / 目标格式 → | Hudi | Iceberg | Delta |
|---|---|---|---|
| Hudi | – | ✅ 实测通过 | ✅ 实测通过 |
| Iceberg | ✅ 实测通过 | – | ✅ 实测通过 |
| Delta | 支持(未实测) | 支持(未实测) | – |
| Paimon(只读源) | 支持 | 支持 | 支持 |
| Parquet(只读源) | ✅ 实测通过 | 支持 | 支持 |
- Hudi、Iceberg、Delta 三者两两互转;Paimon 与 Parquet 是 0.4.0 新增的只读源(只能作为源,不能作为目标)。
- 实测的完整闭环包括:Hudi 表(city 分区、6 行)同步出 Iceberg + Delta 目标并用 Spark 读回;Iceberg 表同步出 Hudi + Delta 目标并读回;Parquet 表同步出三种目标并读回 Hudi 目标;源表追加 2 行后再次同步,目标端增量更新(详见《Apache XTable 0.4 集成使用指南》)。
五、功能特性
- 全方向互转:三大开放表格式两两互转,一份数据同时被三种生态的引擎查询。
- 零数据重写:只同步元数据,同步开销与数据量解耦,大表友好。
- 增量同步:基于水位(源表提交时间)的增量模式,性能远好于全量;异常时自动回退全量。
- 元数据完整同步:schema(含演进)、分区信息、列级统计(min/max/nullCount)一并同步,支撑目标引擎的分区裁剪与数据跳过。
- 目标端元数据维护:Hudi 清理、Iceberg 快照过期、Delta 日志保留期,均可配置。
- Catalog 注册:支持将目标表注册到 Hive Metastore、AWS Glue(Unity、Polaris、Gravitino、DataHub 在路线图中)。
- 多种运行形态:独立 spark-submit、作业内 API、REST 服务、源码模块按需裁剪。
六、适用场景与限制
6.1 适用场景
- 湖仓一体平台需要同时服务多种引擎/生态(如 Spark 写 Hudi、Trino/Flink 读 Iceberg、Databricks 读 Delta),不想为每个引擎维护一份数据拷贝。
- 存量表格式迁移的过渡方案:先以互转方式让新引擎读旧格式表,再逐步灰度切换写入侧。
- 多云/多平台分发:同一张表在不同平台上以不同格式"暴露"。
6.2 限制与注意(0.4.0 实测与官方文档确认)
- 只支持 Copy-on-Write 或 Read-Optimized 视图:只同步 Parquet 基础文件;Hudi 的 log 文件、Delta/Iceberg 的 deletion vectors 不会被同步,MOR 表的实时更新视图不在覆盖范围。
- 读 Hudi 目标表要求 Hudi 0.14.0+,且读取时需开启
hoodie.metadata.enable=true与 hive 风格分区(实测未开启时结果为空,详见集成指南)。 - 0.4.0 构建依赖矩阵敏感:Hudi 0.14.0、Iceberg 1.9.2(需 Avro 1.12.0)、Delta 2.4.0(Spark 3.4 路径);实测与 Hudi 1.2.0 写出的表(timeline layout v2)不兼容,Spark 自带 Avro 1.11 需替换为 1.12.0(排障过程见安装指南常见问题)。
- Parquet 只读源的行数统计缺陷:实测 PARQUET 源同步出的 Delta/Iceberg 目标,文件级
numRecords统计为 0(Hudi 目标不受影响),导致 Delta/Iceberg 端count()返回 0 而 Hudi 端正常,属上游解析器未填充记录数的已知行为,生产使用 PARQUET 源前需评估。 - 项目处于 Apache 孵化器阶段,版本迭代快、API 可能变动,生产跟进官方 Release Note。
七、同类选型对比
开放表格式互操作的主流方案:
| 方案 | 类型 | 数据重写 | 格式覆盖 | 社区活跃度(2026) | 适用 |
|---|---|---|---|---|---|
| Apache XTable 0.4 | 独立元数据同步工具 | 否(仅元数据) | Hudi/Iceberg/Delta 双向 + Paimon/Parquet 只读源 | 中,Apache 孵化器活跃迭代 | 多格式互操作、迁移过渡 |
| Delta UniForm | Delta 内置特性 | 否(生成 Iceberg 元数据) | Delta→Iceberg 单向(Hudi 无) | 高(Databricks 主推) | 已用 Delta Lake 且主要需要 Iceberg 读端 |
| 双写(作业同时写两种格式) | 应用层方案 | 是(数据双份) | 任意组合 | 通用模式 | 一致性要求极高、可接受双倍存储与写入开销 |
| ETL 定期重写 | 数据管道方案 | 是(周期性拷贝) | 任意组合 | 通用模式 | 容忍小时级延迟的离线场景 |
| 引擎自带读取适配 | 引擎特性 | 否 | 有限(如 Spark 读 Delta/冰山借 connector) | 依赖各引擎 | 简单读端需求 |
选型结论:需要 Hudi/Iceberg/Delta 三格式双向互操作、且不愿重写数据——首选 Apache XTable;技术栈已绑定 Delta Lake 且只需补 Iceberg 读能力——可评估 Delta UniForm;仅一两个引擎的读适配需求——优先用引擎自带 connector,不为互操作引入新组件。
八、参考链接
- 官网:https://xtable.apache.org
- 项目主页(孵化器):https://projects.apache.org/project.html?xtable
- 源码仓库:https://github.com/apache/incubator-xtable
- 官方文档(Quick Start):https://xtable.apache.org/docs/how-to
- Spark Runtime 使用指南:https://xtable.apache.org/docs/how-to-spark-runtime
- 下载页:https://xtable.apache.org/releases/downloads
- 0.4.0 发布说明:https://xtable.apache.org/releases/release-0.4.0-incubating
- 功能与限制:https://xtable.apache.org/docs/features-and-limitations