Doris存储与索引模型

针对聚合模型的分析

  • 列式存储,每个列单独存储
  • 数据排序,每个列的数据都根据agg key的顺序进行存储
  • 前缀索引,将agg key组合到一起,取前36个字节,创建一个前缀索引

为什么每一列都需要按照agg key进行排序

最左匹配的时候查找很快,比如说agg key的组合是:bu_id、cat1_id,输入条件where bu_id=1 and cat1_id=102的时候:

  • 先通过最左的bu_id=1找到一波文档编号,bu_id排序的,可以二分查找快速找到文档编号
  • 然后在用这波文档编号去cat1_id的列中去查找符合cat1_id=102的文档编号,bu_id=1对应的cat1_id也是排序的,查找cat1_id=102的时候理论上也可以进行二分查找
  • 再去用最终得到的文档编号去查找指标列的数据,再进行聚合

对于每一列来说,都是文档编号对应列内容的形式,最左列是根据列内容排序的,所以可以很快找到文档编号,其他列都是根据文档编号排序的,所以通过最左列找到文档编号之后,在用文档编号去其他列找对应的内容会很快,因为文档编号排序所以,可以直接二分查找。

文档编号 bu_id Cat1_id
1 1 100
2 1 101
3 1 102
4 2 100
5 2 101
6 2 102
文档编号 bu_id
1 1
2 1
3 1
4 2
5 2
6 2
文档编号 cat1_id
1 100
2 101
3 102
4 100
5 101
6 102

可以发现,第一列是按照bu_id进行排序的,并且也是按照文档编号进行排序的,但是第二列并不是按照cat1_id排序的,仍然是按照文档id排序的,严格上来讲第二列cat1_id是基于bu_id内部按照cat1_id进行排序的。

为什么还需要前缀索引

上面通过多列的方式查找,需要查找两次的,先通过bu_id查找到文档id,在用文档id去cat1_id查找符合条件的cat1_id,前缀索引的作用是将这种多次的查询优化成1次查询。前缀索引的结构大概如下:

文档编号 bu_id&cat1_id
1 1&100
2 1&101
3 1&102
4 2&100
5 2&101
6 2&102

通过前缀索引查询bu_id=1 and cat1_id=102,直接一次查询就能找到文档编号3。

一个有趣的现象

最近在做一个数据源的改造,将es的查询迁移到doris,迁移之后发现,原来es的索引占用空间有10几个G,但是迁移到doris之后,只占用了不到2个G,为什么差异会如此之大?

其实,了解了es和doris的底层储存原理之后,可以很容易发现其中的原因:

es的底层存储结构包括

  • 倒排索引:需要查询的列都需要开启
  • 正排索引:需要排序和聚合的列需要开启
  • 原始文档:写入es的文档,json格式

doris底层存储结构包括

  • 列式存储:对标es的正排索引
  • 前缀索引:相当于一列单独的正排索引
  • 一些其他的稀疏索引:布隆、最大最小值等

很容易发现,es比doris多了倒排索引和原始文档,而且原始文档是json格式,众所周知json格式会有冗余很多key的信息的,这个占了一个大头;对于两者都有的列式存储,至少在es5.x版本,es的列式存储的压缩效率是比较一般的,这部分es占用的空间也会比doris大一些。

下面是一个es索引各种数据结构占用空间的例子:

可以看出,source文件占用了大部分的空间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
_44c.fdt   3.6G source的物理存储文件
_47u.fdt 3.5G source的物理存储文件
_4as.fdt 3.5G source的物理存储文件
_3vj.fdt 3.1G source的物理存储文件
_3vj_Lucene54_0.dvd 1.1G doc_values_document
_4as_Lucene54_0.dvd 1.1G doc_values_document
_44c_Lucene54_0.dvd 1022M doc_values_document
_47u_Lucene54_0.dvd 947M doc_values_document
_4a4.cfs 161M segment比较小的时候,统一保存在这个文件中
_3vj_Lucene50_0.tim 121M 倒排索引的后缀词块
_4as_Lucene50_0.tim 117M 倒排索引的后缀词块
_44c_Lucene50_0.tim 111M 倒排索引的后缀词块
_47u_Lucene50_0.tim 102M 倒排索引的后缀词块
_44c_Lucene50_0.doc 70M 倒排索引的文档列表
_47u_Lucene50_0.doc 67M 倒排索引的文档列表
_4as_Lucene50_0.doc 66M 倒排索引的文档列表

参考链接