Iceberg 导出
GreptimeDB Enterprise 可以通过 Apache Iceberg REST catalog 暴露其表,使得外部查询引擎——pyiceberg、Spark、Trino、DuckDB 以及任何兼容 Iceberg 的客户端——都能使用标准的 Iceberg API 直接从对象存储读取 GreptimeDB 数据。
这是一种只读导出,既不是数据拷贝,也不是双写。GreptimeDB 仍按原有方式写入数据;Iceberg 集成只是发布元数据,让其他引擎能够找到并解读这些相同的文件。
工作原理
关键在于:GreptimeDB 本身就已将 SST(sorted string table)数据文件以 Parquet 格式存储在对象存储中。Iceberg 集成不会重新写入、复制或导出数据,而是发布指向现有 Parquet 文件的 Iceberg 元数据——manifest、manifest-list 以及 table-metadata snapshot。任何支持 Iceberg 的引擎都能通过 REST catalog 读取这些文件。
整体流程如下图所示:
这项工作分布在 GreptimeDB 已有的进程之间:
- Datanode / standalone(写入端)。 每当写入 SST 文件时——包括 flush、compaction、批量写入和 truncate——GreptimeDB 都会将当前存活的 Parquet 文件集合转换为 Iceberg manifest 条目,并提交一个新的 Iceberg snapshot。Iceberg 元数据写入到 datanode 已使用的同一对象存储 bucket 下的
warehouse_root前缀中。 - Frontend(catalog 服务端)。 它实现了 Iceberg REST Catalog API,挂载在
/v1/iceberg,通过直接从对象存储读取元数据向客户端提供每张表当前的元数据——因此 frontend 所需的对象存储配置见配置一节。
由于数据文件从不被复制,因此没有额外的存储开销,也没有写入路径上的重复——导出纯粹是在 GreptimeDB 已写入的数据旁附加的元数据。
GreptimeDB 概念与 Iceberg 的对应关系
| GreptimeDB | Iceberg |
|---|---|
Schema(数据库,例如 public) | Namespace |
| Table(表) | Table |
| Column(列) | Field(字段) |
| 时间索引列 | 一个 timestamp 字段 |
来自 ALTER TABLE(新增 / 重命名 / 删除列)的 schema 变更会反映到 Iceberg schema 中,无需重启。
类型映射
GreptimeDB 列类型到 Iceberg 类型的映射如下:
| GreptimeDB 类型 | Iceberg 类型 |
|---|---|
boolean | boolean |
int8、int16、int32 | int |
int64 | long |
float32 | float |
float64 | double |
string | string |
binary | binary |
date | date |
timestamp(任意精度) | timestamp |
| Prometheus native histogram(struct) | struct(包含 list 子字段) |
uint8、uint16、uint32、uint64 | long — 在 Spark 中不可读(见下文) |
list、dictionary、json、interval、duration、time、任意用户 struct | string(有损降级) |