一、存储

先说Elasticsearch的文件存储,Elasticsearch是面向文档型数据库,一条数据在这里就是一个文档,用JSON作为文档序列化的格式,比如下面这条用户数据:

{ 
"name" : "carl",
"sex" : "Male",
"age" : 18,
"birthDate": "1990/05/10",
"interests": [ "sports", "music" ]
}

这里有一份简易的将Elasticsearch和关系型数据术语对照表:

关系性数据库=>数据库=>表=>行=>列

Elasticsearch=>索引(Index)=>类型(type)(7.x版本正式将type剔除)=>文档 (Docments)
=>字段(Fields)

二、索引

        Elasticsearch最关键的就是提供强大的索引能力了。Elasticsearch索引的精髓用一句话来总结:一切设计都是为了提高搜索的性能,也就是让我们的搜索更快。

2.1 倒排索引

这里我们又应该举个例子我构建一个ES的搜索数据结构模型。那我们的结构化数据怎么储存呢?

我们拿到三条结构化数据:

es索引永久保存 es索引存储原理_elasticsearch

ID是Elasticsearch自建的文档id,那么Elasticsearch建立的索引如下:

Name:

 

es索引永久保存 es索引存储原理_搜索引擎_02

 Age:

es索引永久保存 es索引存储原理_大数据_03

Sex:

 

es索引永久保存 es索引存储原理_大数据_04

2.1.1  Posting List(倒排表)

Elasticsearch分别为每个field都建立了一个倒排索引,Tom,carl, 18, Female这些叫term(分类索引),而[1,2]就是Posting List(倒排表)。Posting list就是一个int的数组,存储了所有符合某个
term的文档id。

通过posting list这种索引方式似乎可以很快进行查找,比如要找age=18的词条,立马就会有人回答,是1和3。但是,如果这里有上千万的记录呢?如果是想通过name来查找呢?

2.1.2 Term Dictionary(词典)

Elasticsearch为了能快速找到某个term,将所有的term排个序,二分法查找term,log(N)的查找效
率,就像通过字典查找一样,这就是Term Dictionary。现在好像跟我们的传统B树的方式一样啊 。那么我们的ES有什么进步呢?

2.1.3 Term Index(词典索引)

B-Tree通过减少磁盘寻道次数来提高查询性能,Elasticsearch也是采用同样的思路,直接通过内存查找term,不读磁盘,但是如果term太多,term dictionary也会很大,放内存不现实,于是有了Term Index,就像字典里的索引页一样,A开头的有哪些term,分别在哪页,可以理解term index是一颗树:

es索引永久保存 es索引存储原理_elasticsearch_05

这棵树不会包含所有的term,它包含的是term的一些前缀。通过term index可以快速地定位到term

dictionary的某个offset,然后从这个位置再往后顺序查找。

es索引永久保存 es索引存储原理_搜索引擎_06

        所以term index不需要存下所有的term,而仅仅是他们的一些前缀与Term Dictionary的block之间的映射关系,再结合FST(Finite State Transducers)的压缩技术,可以使term index缓存到内存中。从term index查到对应的term dictionary的block位置之后,再去磁盘上找term,大大减少了磁盘随机读的次数。

那么Term Index用的是哪种树?

字典树(Tria Tree)

字典树又称之为前缀树(Prefix Tree),是一种哈希树的变种,可以用于搜索时的自动补全、拼写检查、最长前缀匹配等。具体后续在研究

三、其他重要知识:

  1. FST
  2. 压缩技巧之Frame Of Reference
  3. 缓存技巧之Roaring Bitmaps 咆哮位图
  4. 倒排索引如何做联合索引

 内容比较深入,后续再研究...