🗒️Hudi|查询加速
2023-5-24
| 2023-6-12
字数 1296阅读时长 4 分钟
type
status
date
slug
summary
tags
category
icon
password

索引

支持多种索引:HBASE, INMEMORY, BLOOM, GLOBAL_BLOOM, SIMPLE, GLOBAL_SIMPLE, BUCKET
以下索引不建议使用:
  • INMEMRY 索引
根据内存中的索引数据去匹配,基本不可用
  • SIMPLE 索引
根据新数据所在的分区,获取受影响的分区文件列表,直接读取该部分 parquet 文件的 partition_key 和 record_key,与新数据执行 leftOutJoin 产生索引数据,性能低下(以 hoodieKey 为匹配键)
  • HBASE 索引
需要引入额外的 Hbase 服务,业务方基本不会允许
  • GLOBAL_SIMPLE 索引
与 SIMPLE 索引相比,GLOBAL_SIMPLE 索引读取的旧数据是全量数据,以 recordkey为匹配键,性能更低下

BLOOM

写入信息

org.apache.hudi.io.storage.HoodieAvroOrcWriter
org.apache.hudi.avro.HoodieBloomFilterWriteSupport#finalizeMetadata
可以看到这里会写入布隆过滤器序列化后的信息和主键的 MIN/MAX 信息。
写入到 parquet 文件的 footer 中。

读取信息

org.apache.hudi.common.util.BaseFileUtils#readBloomFilterFromMetadata
从 footer 中读取信息,构建布隆过滤器。

结论

还是写入 footer 中,跟 Iceberg 差不多,只是 bloomfilter 的算法可能不同。

GLOBAL_BLOOM

全局索引强制跨表的所有分区的键的唯一性,即保证表中对于给定的记录键恰好存在一条记录。

和 BLOOM 的区别

加载文件时加载全部分区的数据文件
org.apache.hudi.index.bloom.HoodieGlobalBloomIndex#loadColumnRangesFromFiles
org.apache.hudi.index.bloom.HoodieBloomIndex#loadColumnRangesFromFiles
只加载特定分区

结论

这么看,GLOBAL_BLOOM 并不能实现比 BLOOM 更好的性能。

BUCKET

推荐在较大数据量的场景下使用,避免布隆过滤器的假阳性问题。

MetadataTable

MetadataTable 是一张包含元数据的 mor 表,记录了数据表的文件、列统计、布隆过滤器的信息。
写入打标:
column_stat_idx
bloom_filter_idx
bucket_idx
flink_state
Simple
Hbase_idx
Spark
Y
Y
Y
N flink only
Y
Y
Flink
N
N
Y
Y
N spark only
N
MetaDataTable表索引分区构建:
file_idx
column_stat_idx
bloom_filter_idx
Spark
Y
Y
Y
Flink
Y
Y
Y
读取data skipping:
column_stat_idx
bloom_filter_idx
bucket_idx
Spark
Y
N
N
Flink
Y
N
N
MetadataTable 的使用
org.apache.hudi.HoodieFileIndex#lookupCandidateFilesInMetadataTable

结论

dataskip 的时候只使用了 column_stat_idx 信息。

其他优化

TimelineService

构建 timeline 的时候避免从 HDFS 上读取数据文件。
  • Hudi
  • Hudi|增量读源码Hudi|数据质量校验
    Loading...