一、存储
先说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的搜索数据结构模型。那我们的结构化数据怎么储存呢?
我们拿到三条结构化数据:
ID是Elasticsearch自建的文档id,那么Elasticsearch建立的索引如下:
Name:
Age:
Sex:
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是一颗树:
这棵树不会包含所有的term,它包含的是term的一些前缀。通过term index可以快速地定位到term
dictionary的某个offset,然后从这个位置再往后顺序查找。
所以term index不需要存下所有的term,而仅仅是他们的一些前缀与Term Dictionary的block之间的映射关系,再结合FST(Finite State Transducers)的压缩技术,可以使term index缓存到内存中。从term index查到对应的term dictionary的block位置之后,再去磁盘上找term,大大减少了磁盘随机读的次数。
那么Term Index用的是哪种树?
字典树(Tria Tree)
字典树又称之为前缀树(Prefix Tree),是一种哈希树的变种,可以用于搜索时的自动补全、拼写检查、最长前缀匹配等。具体后续在研究
三、其他重要知识:
- FST
- 压缩技巧之Frame Of Reference
- 缓存技巧之Roaring Bitmaps 咆哮位图
- 倒排索引如何做联合索引
内容比较深入,后续再研究...