Doris实时数仓实战
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.3.1 存储引擎

和大多数分析型数据库一样,Doris也是以列存格式存储数据的。数据以列进行连续存储,因为类型相同,因此压缩率极高,节省了磁盘空间。Doris对不同的数据类型还提供了不同的编码方式,如INT类型数据存储会使用BitShuffle编码方式,而字符串类型数据存储会使用字典编码方式。更进一步,Doris还会自动根据列的值的分布情况来切换编码类型,比如对于字符串类型,如果列中的重复值比较多,则不再使用字典编码,而直接切换为Plain Text编码,以避免不必要的空间浪费。

从文件格式看,Doris支持的文件格式和Parquet比较类似。一个数据版本会被分割成最大空间为256MB的Segment,每个Segment对应一个物理文件。Segment通常分为Header、Data Region、Index Region、Footer几个部分。Data Region用于按列存储数据,每一列又被分为多个Page,而Page是Doris的最小数据存储单元,如图1-10所示。

图1-10 Doris文件格式

Index Region负责存储数据的索引。Doris提供了丰富的索引来帮助加速数据的读取和过滤。索引类型大体可分为智能索引和二级索引两种。其中,智能索引是在数据写入时自动生成的,无须用户干预,包括前缀稀疏索引、Min Max索引等。而二级索引是用户可以选择性地在某些列上添加的辅助索引,需要自主选择是否创建,比如Bloom Filter索引、Bitmap索引等。

前缀稀疏索引是建立在排序列结构上的一种索引。存储在文件中的数据是按照排序列有序存储的。基于排序列数据,Doris会每1024行创建一个稀疏索引项,如图1-11所示。索引的Key即当前1024行中第一行的前缀排序列的值。当用户的查询条件包含这些排序列时,Doris可以通过前缀稀疏索引快速定位到起始行。

Min Max索引是建立在Segment和Page上的索引。对于Page级别,Doris都会记录每一列中的最大值和最小值。同样,对于Segment级别,Doris也会记录每一列中的最大值和最小值,如图1-11所示。这样当进行等值或范围查询时,Doris可以通过Min Max索引快速过滤掉不需要读取的行。

图1-11 Doris前缀稀疏索引和Min Max索引示例

当对某一列创建Bloom Filter索引后,Doris会在Page级别创建该列的Bloom Filter数据结构。Bloom Filter索引使用固定空间的位图来快速判断一个值是否存在,非常适合高基数列上的等值查询。

Bitmap索引的Key值是实际的列值,Value值是Key在数据文件中的偏移量。通过Bitmap索引,Doris可以快速定位到列值对应的行号,并且快速取数。该索引比较适合基数较低的列上的等值查询。

除了存储方式和索引结构,Doris在读取逻辑上也有很多优化,比如延迟物化功能会先根据有索引的列,定位一个查询范围,然后根据有过滤条件的列进一步过滤以缩小查询范围,最后读取其他需要读取的列。这种方式可以减少不必要的数据读取,降低查询对I/O的资源消耗。