iceberg底层组织方式
下图是Iceberg中表格式,s0、s1代表的是表Snapshot信息,每个表示当前操作的一个快照,每次commit都会生成一个快照Snapshot,每个Snapshot快照对应一个manifest list 元数据文件,每个manifest list 中包含多个Manifest元数据文件,manifest中记录了当前操作生成数据所对应的文件地址,也就是data file的地址。
基于snapshot的管理方式,Iceberg能够获取表历史版本数据、对表增量读取操作,data files存储支持不同的文件格式,目前支持parquet、ORC、Avro格式。
数据文件 data files
数据文件是 Apache Iceberg 表真实存储数据的文件,一般是在表的数据存储目录的 data目录下,如果我们的文件格式选择的是 parquet,那么文件是以“.parquet”结尾。
例 如 :
Iceberg 每次更新会产生多个数据文件(data files)。
表快照 Snapshot
快照代表一张表在某个时刻的状态。每个快照里面会列出表在某个时刻的所有 data files 列表。data files 是存储在不同的 manifest files 里面,manifest files 是存储在一个 Manifest list 文件里面,而一个 Manifest list 文件代表一个快照。
清单列表 Manifest list
manifest list 是一个元数据文件,它列出构建表快照(Snapshot)的清单(Manifest file)。这个元数据文件中存储的是 Manifest file 列表,每个 Manifest file 占据一行。每行中存储了Manifest file 的路径、其存储的数据文件(data files)的分区范围,增加了几个数文件、删除了几个数据文件等信息,这些信息可以用来在查询时提供过滤,加快速度。
例如:
就是Manifest List 文件。
清单文件 Manifest file
Manifest file 也是一个元数据文件,它列出组成快照(snapshot)的数据文件(data files)的列表信息。每行都是每个数据文件的详细描述,包括数据文件的状态、文件路径、分区信息、列级别的统计信息(比如每列的最大最小值、空值数等)、文件的大小以及文件里面数据行数等信息。其中列级别的统计信息可以在扫描表数据时过滤掉不必要的文件。
Manifest file 是 以 avro 格 式 进 行 存 储 的 , 以 “ .avro ” 后 缀 结 尾 。
详细图解
- HDFS目录
- data目录
- parquet格式data files文件
- metadata目录下存放json元数据文件
- json格式元数据文件
json内容如下:
{
"format-version" : 2,
"table-uuid" : "1fbaf999-cad9-4513-b4aa-fe72fda389a6",
"location" : "hdfs://nameservice/warehouse/hive/a",
"last-sequence-number" : 0,
"last-updated-ms" : 1724985394437,
"last-column-id" : 2,
"current-schema-id" : 0,
"schemas" : [ {
"type" : "struct",
"schema-id" : 0,
"fields" : [ {
"id" : 1,
"name" : "id",
"required" : false,
"type" : "long"
}, {
"id" : 2,
"name" : "count",
"required" : false,
"type" : "long"
} ]
} ],
"default-spec-id" : 0,
"partition-specs" : [ {
"spec-id" : 0,
"fields" : [ ]
} ],
"last-partition-id" : 999,
"default-sort-order-id" : 0,
"sort-orders" : [ {
"order-id" : 0,
"fields" : [ ]
} ],
"properties" : {
"owner" : "xc",
"write.parquet.compression-codec" : "zstd"
},
"current-snapshot-id" : -1,
"refs" : { },
"snapshots" : [ ],
"statistics" : [ ],
"snapshot-log" : [ ],
"metadata-log" : [ ]
}
- Manifest file
文件内容如下:
{u'status': 2, u'data_file': {u'record_count': 3, u'nan_value_counts': [], u'file_format': u'PARQUET', u'column_sizes':
[{u'value': 58, u'key': 1}, {u'value': 85, u'key': 2}], u'equality_ids': None, u'partition': {}, u'split_offsets': [4],
u'value_counts': [{u'value': 3, u'key': 1}, {u'value': 3, u'key': 2}], u'content': 0, u'null_value_counts': [{u'value': 0, u'key':
1}, {u'value': 0, u'key': 2}], u'sort_order_id': 0, u'upper_bounds': [{u'value': '\x04\x00\x00\x00\x00\x00\x00\x00', u'key':
1}, {u'value': '\x04\x00\x00\x00\x00\x00\x00\x00', u'key': 2}], u'lower_bounds': [{u'value':
'\x02\x00\x00\x00\x00\x00\x00\x00', u'key': 1}, {u'value': '\x03\x00\x00\x00\x00\x00\x00\x00', u'key': 2}],
u'file_size_in_bytes': 748, u'key_metadata': None, u'file_path': u'hdfs://nameservice/warehouse/hive/a/data/00000-2-
7608cda8-968a-4199-b82e-446e43dbb60a-00001.parquet'}, u'file_sequence_number': 2, u'sequence_number': 2,
u'snapshot_id': 4905875536637374047L}
- Manifest list(Snapshot)
文件内容如下:
{u'deleted_data_files_count': 0, u'deleted_rows_count': 0, u'partition_spec_id': 0, u'added_rows_count': 3,
u'existing_data_files_count': 0, u'added_snapshot_id': 2085907655093186390, u'content': 0, u'manifest_length': 6721,
u'added_data_files_count': 2, u'min_sequence_number': 1, u'manifest_path':
u'hdfs://nameservice/warehouse/hive/a/metadata/1bcc1d6a-c4ab-40cd-b01d-e5e05507a51f-
m0.avro', u'existing_rows_count': 0, u'sequence_number': 1, u'partitions': []}
总结
上面我们详细把每个结构都进行了图解,最后用一张结构明了的汇总图作为总结: