Elasticsearch 倒排索引和 Doc Values

Elasticsearch 是一个开源的搜索引擎,建立在一个全文搜索引擎库 Apache Lucene 基础之上。Elasticsearch 也是使用 Java 编写的,它的目的是使全文检索变得简单,通过隐藏 Lucene 的复杂性,取而代之的是提供一套简单一致的 RESTful API。

ES 在建立索引的时候,一方面可以建立倒排索引供搜索用,另一方面可以建立 Doc Values,供排序、聚合、过滤等操作使用。倒排索引是搜索引擎的核心,ES 通过 Lucene 的倒排索引技术实现了比关系型数据库更快的过滤。

1. 倒排索引

倒排索引是单词(term or token)到文档 id 的关联关系,每个记录索引的字段都有自己的倒排索引。倒排索引主要包含单词词表(Term Dictionary)和倒排列表(Posting List),通过将文档内容进行分词,即可得到单词词表(Term Dictionary):

单词(term or token)文档 id
ES10001,10003
10001
流行10001
搜索引擎10001,10002
发展10002
历史10002
权威10003
指南10003

单词词表一般以 B+ Tree 的形式缓存在服务器内存中,下图是一个单词词表的示例,单词词表的每个叶子节点都记载了指向倒排列表的指针,比如单词 “搜索引擎” 指向了 10001 和 10002。

ES单词词表B+ Tree示例

倒排列表记录了单词对应的文档集合,由倒排项(Posting)组成,Posting 主要包含文档 id、单词频率(TF,记录该单词在该文档中的出现次数,用于后续相关性算分)、位置(Position,记录单词在文档中的分词位置)、偏移(Offset,记录单词在文档的开始和结束位置)。倒排列表顺序的存储在磁盘文件中,这个文件被称为倒排文件,倒排文件是存储倒排索引的物理文件。

最后我们看下倒排索引的检索流程:

  1. 通过单词词表检索单词,拿到倒排列表的指针,这一步在内存中完成,非常快;
  2. 通过倒排列表的指针获取单词对应的文档集合;
  3. 通过 Doc Values 查询文档 id 的完整内容,返回用户最终结果。

为什么 ES/Lucene 的检索比 MySQL 快?

  • MySQL B+tree 索引是存储在磁盘中的,检索时索引并不能直接找到行,而是先找到行所在的页,通过把整页读入内存,再在内存中查找,故 MySQL 检索时需要若干次的随机访问磁盘操作,索引的 B+tree 高度一般为 2-4 层,查找记录时最多需要 2-4 次 IO;而 ES 的倒排索引是存储在内存中的,通过倒排索引拿到倒排列表的指针,再去磁盘上找 term,磁盘的随机访问次数要比 MySQL 少,性能自然就比 MySQL 要好;
  • 基于分词后的全文检索,ES 分词后,每个 term 都可以利用 FST 高速找到倒排索引的位置,并迅速获取文档 id 列表;而对于 MySQL 而言完全是灾难,MySQL 检索中间的词只能全表扫。

2. Doc Values

当你对一个字段进行排序时,ES 需要访问每个匹配到的文档得到相关的值。倒排索引的检索性能是非常快的,但是在字段值排序时却不是理想的结构。

  • 在搜索的时候,我们能通过搜索关键词快速得到结果集;
  • 当排序的时候,我们需要倒排索引里面某个字段值的集合。换句话说,我们需要 转置 倒排索引。

转置 结构在其他系统中经常被称作 列存储。实质上,它将所有单字段的值存储在单数据列中,这使得对其进行操作是十分高效的,例如排序。

在 ES 中,Doc Values 就是一种列式存储结构,默认情况下每个字段的 Doc Values 都是激活的,Doc Values 是在索引时创建的,当字段索引时,ES 为了能够快速检索,会把字段的值加入倒排索引中,同时它也会存储该字段的 Doc Values。

ES 中的 Doc Values 常被应用到以下场景:

  • 对一个字段进行排序;
  • 对一个字段进行聚合;
  • 某些过滤,比如地理位置过滤;
  • 某些与字段相关的脚本计算。

因为文档值被序列化到磁盘,我们可以依靠操作系统的帮助来快速访问。当 working set 远小于节点的可用内存,系统会自动将所有的文档值保存在内存中,使得其读写十分高速; 当其远大于可用内存,操作系统会自动把 Doc Values 加载到系统的页缓存中,从而避免了 jvm 堆内存溢出异常。

参考:
https://www.elastic.co/guide/cn/elasticsearch/guide/current/inverted-index.html
https://www.elastic.co/guide/cn/elasticsearch/guide/current/docvalues-intro.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值