Elasticsearch 是一个开源、分布式、实时搜索和分析引擎,专门用于处理大规模数据的快速检索与分析。它建立在 Apache Lucene 的基础上,但提供了比 Lucene 更为丰富的功能和友好的RESTful API 接口,使得开发者能够轻松地进行全文搜索、结构化搜索以及对海量数据进行复杂的聚合操作。
Elasticsearch 目前被广泛用于互联网多种领域中。一是搜索领域,相对于 solr,成为很多搜索的不二之选。二是 Json 文档数据库,相对于 MongoDB,读写性能更佳,而且支持更丰富的地理位置查询以及数字、文本的混合查询。三是时序数据分析处理,目前在日志处理、监控数据存储、分析和可视化方面做的非常好。
Lucene 只是一个库,想要使用它必须Java语言来作为开发语言并将其直接集成到你的项目中,更糟糕的事,Lucene 非常复杂,需要摄入了解检索知识来理解它是如何工作的
Elasticsearch 也是使用 Java 开发并且使用 Lucene 作为其核心来实现所有索引和搜索功能,但是它的目的是通过简单的 RESTful API 来隐藏 Lucene 的复杂性,从而让全文检索变的简单。
首先看下什么是正排索引,正排索引指的是文档 ID 到文档内容的索引,简单讲就是通过 ID找内容。
倒排索引(Inverted Index)是根据文档内容找文档,是一种常见的索引结构,他在信息检索领域有重要作用。与传统的正排索引不同,倒排索引以词项为基础,将文档内容映射到词项上,提供了更高效的文本检索和搜索能力。
倒排索引是不可变的,有分段的概念,查询时,所有已知的段按顺序被查询。段是不能被改变的,所以既不能把文档从旧的段中移除,也不能修改旧的段来进行更新。删除数据时并不是真正的删除,而是做上删除标记。
当倒排索引过多时,段是可以进行合并的,当合并段时,就会将有删除标记的文档进行物理删除。
倒排索引主要包含两个核心部分:
单词词典(Lexicon):记录了文本集合中出现过的所有不重复的单词(或者其它可作为查询单位的术语),并为每个单词提供一个唯一的标识符(通常是整数)。这个部分相当于一个字典,可以迅速找到与给定单词相关的倒排列表。
倒排文件(Posting List 或 Inverted List):对于词典中的每个单词,倒排文件包含了所有包含该单词的文档列表及其在文档中的位置信息(有时还包括频率信息,如TF-IDF权重等)。这意味着,当你想要查找包含特定单词的所有文档时,可以直接通过倒排索引迅速定位到相应的文档列表,而不需要逐个检查文档。
假设有两个文档
为了创建倒排索引,我们首先将每个文档的content域拆分成单独的词(称为词条或tokens),创建一个包含所有不重复词条的列表,然后列出每个词条出现在哪个文档。
Elasticsearch 为了能很快速找到某个 term,将所有的 term 排个序,二分法查找 term,LogN 的查找效率,就像通过字典查找一样,这就是 Term Dictionary。似乎和传统数据库通过 B-Tree 的方式类似。
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之间的映射关系,再结合FST(Finite State Transducers)的压缩技术,可以使term index缓存到内存中。从term index查到对应的term dictionary的block位置之后,再去磁盘上找term,大大减少了磁盘随机读的次数。
首先看下Elasticsearch的架构图,下面分别介绍一下其核心概念。
注意:分片数据在索引创建时就已经确定下来了,是不能被修改的。
关于Elasticsearch相关概念就介绍到这里,后边继续介绍相关的功能。