简介
Hudi 的 Schema 通过 AVRO 格式定义,常见的一些内置数据会在 hudi-common/src/main/avro
中定义,例如 HoodieMetadata.avsc
定义元数据。
在 Base
和 Log
的数据文件中都保存了写入数据时的相关表结构信息。
Spark
使用时不同的 Spark 版本启动参数略有区别,详细可以参考 Spark Quick Start 中的详细介绍,对于 Schema Evolution
来说,关键的是如下的配置。
spark.sql.catalog.spark_catalog=org.apache.spark.sql.hudi.catalog.HoodieCatalog
修改表结构之后,会通过 deltacommit
的 Timeline
信息中保存当前的表结构信息,在 inflight
中对应了 "operationType": "ALTER_SCHEMA"
,而在结束时包含了之前以及当前的 Schema
信息。
当配置了 hoodie.schema.on.read.enable=true
参数后,也就是开启 On Read
配置,会同时在 .hoodie/.schema
目录下保存对应的元数据。
源码解析
读取
TableSchemaResolver.getTableAvroSchema() 默认最新,可以指定 Instant 获取某个时间点
|-HoodieTimeline.findInstantsBeforeOrEquals() 过滤某个之间点之前,如果传入的时间戳,否则直接调用如下函数
|-TableSchemaResolver.getTableAvroSchemaInternal() 将 Instant 作为 Optional 参数传入
|-TableSchemaResolver.getTableSchemaFromCommitMetadata() 根据 Instant 获取
|-TableSchemaResolver.getTableSchemaFromLatestCommitMetadata() 获取最新
|-HoodieTableConfig.getTableCreateSchema() 如果获取不到,则从 Properties 中获取
|-TableSchemaResolver.getTableAvroSchemaFromDataFileInternal()
|-TableSchemaResolver.getLatestCommitMetadataWithValidData()
| |-HoodieActiveTimeline.getLatestCommitMetadataWithValidData()
| |-HoodieActiveTimeline.getCommitMetadataStream() 会读取 Timeline 中的内容,返回数据文件还存在的第一个 Instant 信息
|-TableSchemaResolver.fetchSchemaFromFiles()
|-TableSchemaResolver.readSchemaFromLogFile()
|-TableSchemaResolver.readSchemaFromBaseFile()