概述
Deletion vector 是用来提升paimon表的读取性能的一种配置,是paimon0.8版本新增的一种机制。主要是通过在写入时生成deletion file(牺牲了部分写入性能),这样在读取数据时,可以根据deletion file对需要读取的数据进行过滤,这样就避免了不同文件的合并成本。文件存储在:manifest-index-manifest-5d670043-da25-4265-9a26-e31affc98039-0

使用方式
配置中指定'deletion-vectors.enabled' = 'true'。
使用限制
changlog-producer 需要被设置成none或者lookup
changlog-producer.lookup-wait 不能设置为false.
merge-engine不能是first-row
这个模式需要过滤过滤level-0层数据,因此在使用时间旅行读取APPEND快照时,将存在数据延迟。
实现
当用户对旧数据进行更新时,会产生一个delete file,此文件主要用来标识data file中哪一条数据被删除了。
paimon-deve.png
delete file文件的结构如下:
paimon-deve-2.png
一个bucket中一个delete file,delete file 中数据的存储结构为map<file_name, bitmap>,当读取指定的数据文件时,首先将delete file 读取进来根据file_name 构建一个bitmap,之后在读取数据文件并根据bitmap将数据过滤。
在compact时生成新的delete file并且标记旧的delete file删除。delete file依赖对应的快照。
JSON

{
  "org.apache.paimon.avro.generated.record": {
    "_VERSION": 1,
    "_KIND": 0,
    "_PARTITION": "\u0000\u0000\u0000\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000p\u0000\u0000\u0000\u0000\u0000\u0000",
    "_BUCKET": 0,
    "_TYPE": "DELETION_VECTORS",
    "_FILE_NAME": "index-32f16270-5a81-4e5e-9f93-0e096b8b58d3-0",
    "_FILE_SIZE": x,
    "_ROW_COUNT": count of the map,
    "_DELETION_VECTORS_RANGES": "binary Map<String, Pair<Integer, Integer>>", key is the fileName, value is <start offset of the serialized bitmap in Index file, size of the serialized bitmap>
  }
}

Write
基于compact+lookup 的deleteFile的生成机制:

  1. 新数据被写入到level0层。
  2. 每次写入后执行压缩,并且强制合并level0层数据
  3. 实现一个类似LookupDeleteFileMergeFunctionWrapper的合并,它具有以下特征:
    a. 当记录不属于level0层时,不产生删除。
    b. 当记录属于level0层+level x层时,不生成删除。(compact时选中的被压缩的层 level 0 层与level x层,都有此数据)
    c. 当记录只属于level 0层时,查找其他层生成 deletefile的map(compact时选中的被压缩的层只有level 0层有此数据)
  4. compact结束后,旧文件中的bigmap不再使用,会生成一个新的文件里面有新的bigmap。

Read
Compaction的优化主要在于批式读取时候可以并发读取单个bucket的文件,之后借助deletefile将历史文件中的数据清除就可以。如果没有delefile,MOR读取方式需要单个并发度去读取一个bucket,因为需要做排序,去除历史的数据。由于deletefile是在compaction时产出,因此读取时候不能读取Level0层的文件结果。
示例:
paimon-deve-3.png
测试
本次测试只是针对数据准确性的测试,不再进行压测,官方压测结果可参考https://mp.weixin.qq.com/s/7VptRdZU6mGQlPiv4silEA
新增一些数据
SQL

insert into test_ver values(1,1);
insert into test_ver values(2,2);
insert into test_ver values(3,33);
update test_ver set age = 2 where (user_id=1 or user_id = 2);

查看生成的index file
JSON

{
        "org.apache.paimon.avro.generated.record": {
                "_VERSION": 1,
                "_KIND": 0,
                "_PARTITION": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
                "_BUCKET": 0,
                "_INDEX_TYPE": "DELETION_VECTORS",
                "_FILE_NAME": "index-6d72d7bc-a6b8-4643-9e34-80bdb80ffd4c-0",
                "_FILE_SIZE": 33,
                "_ROW_COUNT": 1,
                "_DELETIONS_VECTORS_RANGES": {
                        "array": [{
                                "org.apache.paimon.avro.generated.record__DELETIONS_VECTORS_RANGES": {
                                        "f0": "data-f854406a-f936-449e-a66c-1c4e1446c5b1-0.orc",
                                        "f1": 1,
                                        "f2": 24
                                }
                        }]
                }
        }
}

注意
设置'deletion-vectors.enabled' = 'true',读取全量数据依赖compact快照,如果将表设置成write-only表并且没有启动compact任务,使用批查询,或者流式查询历史全量的datafile将查询不到数据。

标签: none

评论已关闭