暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【AntDB分布式数据库的发展展望】分布式数据库优化方案 - OLAP性能优化(列式储存)

北陌 2024-02-26
33

现阶段 AntDB 已经具备 OLAP 的所有功能,但在性能方面还需要进一步优化,主要在两个方面进行优化:列式存储和向量化执行引擎。下面分别加以说明。

1. 列式存储

列式存储在处理 OLAP 方面有如下几点优势:

这里简要地介绍列式存储的优势,详细解释参见论文 ColumnStores vs. RowStoresHow Different Are They Really?

(1) 数据以列连续存储,查询时只需读取相关的列,降低 I/O,提高查询效率。

(2) 同一个列中数据类型相同,可以根据数据类型选择合适的编码和压缩方式,成倍地降低 I/O,进一步提高查询效率,查询时涉及解压过程,I/O 降低带来的性能提升明显大于解压带来的性能损耗,所以整体来讲性能是提 升的。

(3) 由于相同的列连续存储,查询时磁盘 I/O 是顺序读比随机读快很多, 在计算时可以充分利用 CPU 的 Cache Line 和高速缓存,还可以使用 simd 指令进一步提高计算性能。

(4) 延迟物化,把映射下推和谓词下推发挥到极致,大大提高查询效率。

要理解延迟物化,首先了解一下物化:为了能够把底层存储格式(面向Column 的)和用户查询表达的意思(Row)对应上,在一个查询的生命周期的某个时间点,一定要把数据转换成 Row 的形式,这在 Column-Store 里面被称为物化(Materization)。

理解了物化的概念之后,延迟物化就很好理解了,即把这个物化的时机尽量地拖延到整个查询生命周期的后期。使参与中间计算的数据尽可能少。

举个例子:

select name from person where id > 10 and age > 20;


一般(Naive)的做法是从文件系统读出三列的数据,马上物化成一行行的 person 数据,然后应用两个过滤条件:id > 10 和 age > 20 ,过滤完了之后从数据里面抽出 name 字段,作为最后的结果。

延迟物化的做法则先不拼出行式数据,直接在Column 数据上分别应用两个过滤条件,从而得到两个满足过滤条件的 bitmap,然后再把两个 bitmap 做位与(bitwise AND)的操作,得到同时满足两个条件的所有 bitmap,因为最后用户需要的是 name 字段,因此下一步拿着这些 position 对 name 字段的数据进行过滤就得到了最终的结果。如图 7-4 所示。



(5) 隐式连接,采用延时物化的方法,使多表 join 过程,映射下推和谓词下推发挥到极致,大大提高 join 查询效率。

举例:有一个星形结构的数仓模型,start-schema 是教科书般的测试模型, 因而适合用来做试验并验证本文的观点。如图 7-5 所示。


● 下推相关条件到各个维度表,提炼出被事实表关联的主键列表(也就是事实表的外键),并构建对应的Hash table(Key是外键值,Value是外键在维度表中的position),如图7-6所示。

● 对多个事实表以外键关联维度表的列进行探测,查找对应的Hash table,过滤出多个Position List(与被关联的列相关),然后对多个Position List求交集(比如前文提到的Bitmap的AND计算等),得到一个最终的Position List,如图7-7所示。

● 基于前面的Position List,最终从事实表中找到需要投影的其他列,而通过Hash table从维度表找到需要投影的其他列,Hash table中的Value是维度表中的Position,所以可以快速定位维度表的其他列,如图7-8所示。


前面列式存储的优点中,(3)、(4)、(5)点需要配合向量执行引擎才能发挥出来。

AntDB 中列式存储采用写优化的行列混存格式,本质上就是 LSM Tree 和Parquet 的结合体,其结构如图 7-9 所示。

Pack 也可以称为行组(Row Group),通常一个 Pack 包含 8K 行或者更多的数据。每个 Pack 内按列连续存储称为列块(Column Chunk),Pack 除了主键列(Primary Keys,PK)以及 Schema 包含的列之外,还额外包含 Version 列和 Del_mark 列。Version 就是事务的 Commit 时间戳,通过它来实现 MVCC。del_mark 是布尔类型,表明这一行是否已经被删除。

Delta Layer 相当于 LSM Tree 的 L0,它可以认为是对列存表的增量更新,所以命名为 Delta。与 LSM Tree 的 MemTable 类似,最新的数据会首先被写入一个称为 Delta Cache 的数据结构,当写满之后会被写入磁盘上的 Delta Layer。而当Delta Layer 写满之后,会与 Stable Layer 做一次 Merge 得到新的 Stable Layer。

Stable Layer 相当于 LSM Tree 的 L1,是存放列存表大部分数据的地方。Stable Layer 同样由 Pack 组成。不一样的是 Stable Layer 中的数据是全局有序, 而 Delta Layer 则只保证 Pack 内有序。原因很简单,Delta Layer 的数据是从Delta Cache 写下去的,各个 Pack 之间会有重叠;而 Stable Layer 的数据则经过了 Delta Merge 的整理,可以实现全局有序。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论