ElasticSearch

1.elasticsearch是什么

ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。能够达到实时搜索,稳定,可靠,快速,安装使用方便

应用案例

1.Github:GitHub使用ElasticSearch搜索20TB的数据,包括13亿文件和1300亿行代码。

2.elasticsearch能做什么

    1、全文搜索(搜索引擎)

        在一组文档中查找某一单词所在文档及位置

    2、模糊匹配

        通过用户的输入去匹配词库中符合条件的词条

    3、商品搜索

        通过商品的关键字去数据源中查找符合条件的商品

3.elasticsearch的优势


ElasticSearch_第1张图片


    名词概念


ElasticSearch_第2张图片
ElasticSearch_第3张图片

1.天生支持分布式

Elasticsearch天生就是分布式的,它知道如何管理节点来提供高扩展和高可用。

1.添加索引

ElasticSearch_第4张图片

2.增加故障转移

ElasticSearch_第5张图片

3.横向扩展

ElasticSearch_第6张图片

4.继续扩展

ElasticSearch_第7张图片

5.应对故障

ElasticSearch_第8张图片

2.倒排索引

ElasticSearch_第9张图片


ElasticSearch_第10张图片

 可以看到,倒排索引是per field的,一个字段由一个自己的倒排索引。18,20这些叫做 term而[1,3]就是posting list。Posting list就是一个int的数组,存储了所有符合某个term的文档id。

那么什么是term dictionary 和 term index?

         假设我们有很多个term,找出某个特定的term一定很慢,因为term没有排序,需要全部过滤一遍才能找出特定的term。排序之后我们可以用二分查找的方式,比全遍历更快地找出目标的term。这个就是 term dictionary。有了term dictionary之后,可以用 logN 次磁盘查找得到目标。

          但是磁盘的随机读操作仍然是非常昂贵的所以尽量少的读磁盘,有必要把一些数据缓存到内存里。但是整个term dictionary本身又太大了,无法完整地放到内存里。于是就有了term index。term index有点像一本字典的大的章节表。比如:A开头的term ……… Xxx页;C开头的term ……… Xxx页;E开头的term ………Xxx页。

ElasticSearch_第11张图片

term index压缩

       例子是一个包含 "A", "to", "tea", "ted", "ten", "i", "in", 和 "inn" 的 trem 树。这棵树不会包含所有的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,大大减少了磁盘随机读的次数。

FST是啥

        假设我们现在要将mop, moth, pop, star, stop and top(term index里的term前缀)映射到序号:0,1,2,3,4,5(term dictionary的block位置)。最简单的做法就是定义个Map,大家找到自己的位置对应入座就好了,但从内存占用少的角度想想,有没有更优的办法呢?答案就是:FST

关于FST的博文:https://www.cnblogs.com/jiu0821/p/7688669.html

term dictionary压缩

Term dictionary在磁盘上是以分block的方式保存的,一个block内部利用公共前缀压缩,比如都是Ab开头的单词就可以把Ab省去。这样term dictionary可以比b-tree更节约磁盘空间。


ElasticSearch_第12张图片

        现在我们可以回答“为什么Elasticsearch/Lucene检索可以比mysql快了。Mysql只有term dictionary这一层,是以b-tree排序的方式存储在磁盘上的。检索一个term需要若干次的random access的磁盘操作。

为了提高查询的效率,减少磁盘寻道次数,将多个值作为一个数组通过连续区间存放,一次寻道读取多个数据

ElasticSearch_第13张图片
B-tree

而Lucene在term dictionary的基础上添加了term index来加速检索,term index以树的形式缓存在内存中。从term index查到对应的term dictionary的block位置之后,再去磁盘上找term,大大减少了磁盘的random access次数。


posting list压缩技巧

Elasticsearch里除了上面说到用FST压缩term index外,对posting list也有压缩技巧。”posting list不是已经只存储文档id了吗?还需要压缩?”

嗯,我们再看回最开始的例子,如果Elasticsearch需要对同学的性别进行索引,会怎样?如果有上千万个同学,而世界上只有男/女这样两个性别,每个posting list都会有至少百万个文档id。 Elasticsearch是如何有效的对这些文档id压缩的呢?

Frame Of Reference

增量编码压缩,将大数变小数,按字节存储

首先,Elasticsearch要求posting list是有序的(为了提高搜索的性能,再任性的要求也得满足),这样做的一个好处是方便压缩,看下面这个图例:

联合索引

上面说了半天都是单field索引,如果多个field索引的联合查询,倒排索引如何满足快速查询的要求呢?

利用跳表(Skip list)的数据结构快速做“与”运算,或者

利用上面提到的bitset按位“与”

先看看跳表的数据结构:

将一个有序链表level0,挑出其中几个元素到level1及level2,每个level越往上,选出来的指针元素越少,查找时依次从高level往低查找,比如55,先找到level2的31,再找到level1的47,最后找到55,一共3次查找,查找效率和2叉树的效率相当,但也是用了一定的空间冗余来换取的。

跳表原理:https://www.cnblogs.com/a8457013/p/8251967.html

假设有下面三个posting list需要联合索引:

如果使用跳表,对最短的posting list中的每个id,逐个在另外两个posting list中查找看是否存在,最后得到交集的结果。

你可能感兴趣的:(ElasticSearch)