前言
相比于大多数人熟悉的MySQL数据库的索引,Elasticsearch的索引机制是完全不同于MySQL的B+Tree结构。索引会被压缩放入内存用于加速搜索过程,这一点在效率上是完爆MySQL数据库的。但是Elasticsearch会对全部text字段进行索引,必然会消耗巨大的内存,为此Elasticsearch针对索引进行了深度的优化。在保证执行效率的同时,尽量缩减内存空间的占用。这篇文章就深度解析了Elasticsearch索引原理,揭开搜索的神秘面纱。
简介
Elasticsearch是一个基于Lucene库的开源搜索引擎,它提供分布式的实时文件存储和搜索,可扩展性好,并且支持通过HTTP网络接口交互,数据以JSON格式展示。
Elasticsearch因为其极快的搜索和聚合速度通常被应用在各种搜索应用中,比如在自己的app里面加一个搜索框或者分析实时日志(ELK系统)。
Elasticsearch会对所有输入的文本进行处理,建立索引放入内存中,从而提高搜索效率。在这一点上ES要优于MySQL的B+树的结构,MySQL需要将索引放入磁盘,每次读取需要先从磁盘读取索引然后寻找对应的数据节点,但是ES能够直接在内存中就找到目标文档对应的大致位置,最大化提高效率。并且在进行组合查询的时候MySQL的劣势更加明显,它不支持复杂的组合查询比如聚合操作,即使要组合查询也要事先建好索引,但是ES就可以完成这种复杂的操作,默认每个字段都是有索引的,在查询的时候可以各种互相组合。
为了省事,以下统一用ES来代替Elasticsearch,其实我们在公司里面也基本都说ES,全称比较难读。还有一点,因为ES使用了Lucene的库,下面说的很多优化思路都是Lucene里面的,但是为了讲解方便,我就用ES来代替Lucene。
索引
首先需要申明的是在ES中索引的概念和MySQL里面的概念不太一样,这里列出一下ES和MySQL的对应的概念,方便大家理解。
MySQLES库(database)索引(index)表(table)类型(type)行(row)文档(doc)列(column)字段(field)
在ES中每个字段都是被索引的,所以不会像MySQL中那样需要对字段进行手动的建立索引。
ES在建立索引的时候采用了一种叫做倒排索引的机制,保证每次在搜索关键词的时候能够快速定位到这个关键词所属的文档。
Inverted Index
比如有三句话在数据库中:
- Winter is coming
- Ours is fury
- Ths choice is yours
如果没有倒排索引(Inverted Index),想要去找其中的choice
,需要遍历整个文档