es的速度快是多方面的原因,此篇博文主要从数据存储方面来解释为什么es的速度快。

首先我们要有几个基本认知:

  1. es中的一个shard就是一个Lucene Index。
  2. Lucene Index中有很多小Segments, 即为存储的最小管理单元

为什么要说明es和lucene之间的关系呢?

因为es是在Apache Lucene的基础上开发的,而且倒排索引是在segments的维度上实现的。

1. 什么是倒排索引?

其实这个名词的翻译给人有种误解,感觉上是对索引进行了倒排序,但其实不是这样子的。它的英文原文是:inverted index, 有种颠倒的意思在里面。 回想我们使用的关系型数据中的索引, 我们是通过索引来定位记录,倒排索引是根据属性值来确定记录的位置。 所以倒排索引也常被称为反向索引。

如下是Lucene中实际的索引结构:

ES慢查询原因及分享 es查询速度为什么快_ES慢查询原因及分享


下面我们会一 一讲解上述三个概念。

2. 实例讲解:

场景: 假设我们有一个es的集群,并且在该集群中创建了索引people,people具有如下字段:

sex, age, height, name

我们向people中插入几条数据,会有如下的记录存在于es(省略了一些默认字段):

ES慢查询原因及分享 es查询速度为什么快_java + es_02


接下来es会为每个term创建一个docId列表(Posting List)。

2.1. Posting List

posting list 存储的是所有符合特定term的文档id(在实际的搜索引擎中存储的并不都是文档的id,取而代之的是文档id的偏移量,这样就可以把大数据的存储转成小数据的存储。 例如: 100-》120-》150 变成了100 -》20-》30)。除此之外还包含:文档的数量、词条在每个文档中出现的次数、出现的位置、每个文档的长度、所有文档的平均长度等,在计算相关度时使用。

ES慢查询原因及分享 es查询速度为什么快_大数据_03

2.2. Term Dictionary

假设我们的有很多的人员数据,那么我们的Posting list会变得很大,这时候查询的速度肯定会变慢,于是我们对term进行排序,排序之后使用二分查找就能更快的查找出目标,这就是Term Dictionary。

对于age我们有以下的term dictionary:

18,20,21

使用了二分查找之后时间复杂度降低到了Log N,磁盘的IO次数也降低到了Log N。

尽管有了Term Dictionary,但是磁盘的随机访问(Random access)仍然是昂贵的, 所以为了再次提升性能,可以考虑把一部分数据直接读到内存中,但是term dictionary又太大了, 全部缓存到内存是不现实的,于是就有了Term Index(对Term本省进行索引)。

2.3. Term Index

Term Dictionary是term的有序集合,那么Term Index就类比字典的大章节目录。

A --------------------第1页
	  abxxxx--------------第2页
	  acxxx---------------第3页
   B ---------------------第4页

如果我们的Term都是英文,那么这个Term Index只需要26个字母就够了,但实际情况是term可以是任意的byte数组。而且 26 个英文字符也未必是每一个字符都有均等的 term,比如 x 字符开头的 term 可能一个都没有,而 s 开头的 term 又特别多。实际的 term index 是一棵 变种的trie 树(Finite State Transducers (FST) 一种有限状态转移机)。

为什么是FST?

Trie树共享的是前缀,而FST既共享前缀也共享后缀。

优点:

  1. 空间占用小, 通过对词典中单词前缀和后缀的重复利用,压缩了存储空间。
  2. 查询速度快。O(len(str))的查询时间复杂度。

对比:

  • 假设我们有以下个单词
do    dog   does  deep   cost

它们对应的Trie树和FST分别是:

Trie:

ES慢查询原因及分享 es查询速度为什么快_java + es_04


FST:

ES慢查询原因及分享 es查询速度为什么快_ES慢查询原因及分享_05

从上面的图可以看出来Term Index只保留Term的前缀和后缀,再加上一系列的压缩技术(比如前面提到的使用偏移量而不是真正的id),Term Index可能只有Term Dictionary的几十分之一,甚至更少,这样使得内存缓存整个Term Index成为可能。

未完待续。。。。。。。