Apache Paimon-file index
概述
索引是用于加速数据查询和访问的重要数据结构,用户可以对某些字段设置索引,进行查询时可以加快检索的速度,当前Paimon 支持的索引有BloomFilter与Bitmap两种索引,当前0.9.0版本索引支持append only表结构,代码master分支已经支持了主键表。
File Index原理
文件索引本质上是在写入数据时格外针对进行索引的字段写一份用于索引的索引文件,然后在用户进行数据查询时根据用户指定的where 语句里面的匹配规则先根据索引文件进行一次过滤.
Paimon整体过滤流程如下:
读取
Flink 在使用consumerid模式消费paimon时会产生两个节点,一个是monitor节点(读取元数据产出元数据)一个是reader节点(真正去并发读取数据),其中monitor主要是用来读取快照信息,并根据一些过滤条件对paimon的元数据进行过滤,最终产出split(经过一系列过滤产出的元数据信息)下发到reader的节点。reader节点在根据splits信息去真正到hdfs上读取数据。
Paimon的Index有两个地方可以存储一个是存储到Manifest中(当index文件较小时),另外是存储在datafile中(当index文件较大时)threshold是500bytes。(如果index特别大,放在monitor中读取有OOM风险)
我们可以看上图,通过索引进行过滤可以在scan时进行,也可以在真正读取数据时进行。Paimon在实现FlinkSource时继承实现了Flink的SupportsFilterPushDown会将filter信息传输给Paimon如下图:
Index在元数据
Paimon获取到Flink传来的Filter之后会转换成自己的Predicate,之后逐级传输下去,最终在AbstractFileStoreScan&plan中对获取的元数据进行过滤,如下图在我圈出来的地方都会进行过滤,不只是根据index进行过滤Paimon之前也有些过滤Partition等等之类的优化也在这块。
index在数据文件
读取数据文件相关逻辑在Flink的ReadOperater中,在processElement方法读取Split时对数据进行过滤。
写入
写入就是在写数据之前向index文件中写一份。
存储格式
_____________________________________ _____________________
| magic |version|head length |
|-------------------------------------|
| column number |
|-------------------------------------|
| column 1 | index number |
|-------------------------------------|
| index name 1 |start pos |length |
|-------------------------------------|
| index name 2 |start pos |length |
|-------------------------------------|
| index name 3 |start pos |length |
|-------------------------------------| HEAD
| column 2 | index number |
|-------------------------------------|
| index name 1 |start pos |length |
|-------------------------------------|
| index name 2 |start pos |length |
|-------------------------------------|
| index name 3 |start pos |length |
|-------------------------------------|
| ... |
|-------------------------------------|
| ... |
|-------------------------------------|
| redundant length |redundant bytes |
|-------------------------------------| ---------------------
| BODY |
| BODY |
| BODY | BODY
| BODY |
|_____________________________________| _____________________
column number:索引列数量
column 1:被索引的某一列
index number:这一列设置的索引类型个数(支持某一列设置多个索引)
index name 1 |start pos |length :索引名,以及索引的开始位置,长度。
BODY:具体索引内容
Bloom Filter
使用方式
file-index.bloom-filter.columns配置,配置用户想要增加索引的字段。
file-index.bloom-filter.<column_name>.fpp配置此列允许的错误率 默认0.1
file-index.bloom-filter.<column_name>.items配置此列预期的非重复项 默认100000
限制
- 对于新建的表来说直接设置'file-index.bloom-filter.columns'字段就可以,对于旧表,需要回刷一下索引文件回刷接口CALL sys.rewrite_file_index(
table
=> 'test_db.T'),并且写入旧表的任务重启下确保索引相关配置生效。 - 不支持的数据类型 Array、mutiset、map、row、decimal、boolean
原理
Bloom Filter主要是对于=进行过滤,当用户查询时select * from t where b=1;首先会查找bloom过滤中是否有这种数据 bloomfiter中如果没有此数据就直接返回空,如果有的话在进一步查寻具体的数据表。
Bitmap
使用方式
在配置中添加file-index.bitmap.columns
限制
- 对于新建的表来说直接设置'file-index.bitmap.columns'字段就可以,对于旧表,需要回刷一下索引文件CALL sys.rewrite_file_index(
table
=> 'test_db.T'),并且写入旧表的任务重启下确保索引相关配置生效。 不支持的数据类型
Map Row Mutiset Array Decimal Binary Varbinary
原理
Bitmap 索引 会将索引的字段存储到bitmap中,每次where 条件中有bitmap中的字段,会先在bitmap查询数据是否存在,如果存在的话在继续查询读取数据,如果不存在直接返回空,可以对in,=,not in等过滤。
评论已关闭