美文网首页
Elasticsearch 搜索与聚合在数据存储结构方面的理解

Elasticsearch 搜索与聚合在数据存储结构方面的理解

作者: xuxiangwork | 来源:发表于2018-02-26 17:59 被阅读0次

    1、说说 Elasticsearch 的搜索与聚合在数据存储结构方面的理解。

    1)Elasticsearch 在搜索时,采用的是倒排索引(也称反向索引)。即将文档的所有内容通过分析、过滤、转化等操作抽取关键字,然后建立一个按字符顺序排列的关键字列表。

    假设有两篇文章:

    文章1的内容是: Tom lives in Guangzhou, I live in Guangzhou too.

    文章2的内容是: He once lived in Shanghai.

    文章内容经过 Elasticsearch 的分析器处理后,得到如下的关键词:

    文章1的关键词是: tom live guangzhou i live guagnzhou

    文章2的关键词是: he live shanghai

    得到上述文章的关键字之后,可以构造出如下的索引表

    term 文章1 文章2
    guangzhou *
    he *
    i *
    live * *
    shanghai *
    tom *

    当然,仅仅知道关键词出现在那些文章还是不够的,我们希望还能够得到文章的关键词出现的次数和出现频率。而 lucene 中采用的索引结构类似为:

    term 文章号[出现频率] 出现位
    guangzhou 1[2] 3、6
    he 2[1] 1
    i 1[1] 4
    live 1[2]、2[1] 2、5、2
    shanghai 2[1] 3
    tom 1[1] 1

    我们以 live 这样说明该结构。live 在文章1中出现了2次,文章2中出现了一次。它的出现位置为 2、5、2 代表的含义需要结合文章号和出现频率来分析。文章1中出现了2次,那么 2、5 就表示 live 在文章1中出现的两个位置,文章2中出现了一次,剩下的 2 就表示 live 是文章 2 中第 2 个关键字。

    上述的关键字是按字符排序排列的,因此 lucene 可以用二元搜索算法快速定位关键词。实现时 lucene 将上面表格的三列分别作为词典文件、频率文件、位置文件保存。此种词典文件不仅保留关键词,还保留了指向频率文件和位置文件的指针。

    假设要查询单词 live ,lucene 先对词典二元查找,找到改词后,通过指向频率文件的指针读取所有文章号。因此词典文件本身特别小,因而整个过程是毫秒级的。

    相比如普通的顺序匹配,对文章内容进行字符串匹配,lucene 的倒排索引是相当快速的。

    2)上面分析完 Elasticsearch 在搜索时采用的倒排索引,下面说一下 Elasticsearch 的聚合分析。聚合分析和搜索还是有很大的不同,典型的应用场景,比如计算文章1中每个关键词出现的次数,反向索引就略显无力。首先需要扫描整个词典文件,才能找到该文档包含的所有关键词,然后在进行聚合统计。在数据量大的情况下,扫描整个方向索引,性能肯定要受不小影响。

    Elasticsearch 为聚合计算引入名为 fielddata 的数据结构,即采用我们平时常见正向索引,即文档到关键词的映射。类似于下表:

    文章号 guangzhou he i live shanghai tom
    文章1 * * * *
    文章2 * * *

    对文章在进行聚合计算时,就只要根据文章 ID 查找就好。因为聚合计算也好,排序也好,通常是针对某些列,实际上 Elasticsearch 为了做聚合分析,生成的是文档到 field 的多个列式索引(至于什么是列式索引,后面做详细介绍)。在做聚合就分析,fielddata(类似上表) 是保存在内存中,这么做会有内存不够用的风险,而且内存是从 JVM (java 虚拟机)上分配的,JVM 对大内存的垃圾收集有一定不稳性。当数据量大时,内存不够是正常的,同时,也不可能一次性所有字段都加载,如果未命中搜索,还需要在内存中建立 fielddata ,这都影响响应时间。

    为了解决 fielddata 的内存有限和 JVM 对大内存的垃圾回收导致的不稳定问题,Elasticsearch 引入如 DocValue。DocValue 也是和 fielddata 类似的结构。不同的是,DocValue 是持久存取在文件中。由于这消耗了额外的存储空间,但对于 JVM 的内存需求降低,多余的内存留给操作系统的文件缓存使用。加上DocValue 是预先构建的,查询时剩去了不命中是构建 fielddata 的时间。DocValue 比内存慢10%~25%,但是稳定性大幅提升。

    3)何为列式存储?

    看下图:


    20141115094556515.png

    从上图的内存结构可以看出,行式存储下,一张表的数据时放在一起的,但是列式存储则是分开保存。优缺点如下:


    image2016-9-23 11_15_43.png

    相关参考网址:

    http://blog.csdn.net/dc_726/article/details/41143175 (几张图看懂列式存储)

    https://yq.aliyun.com/articles/6902?do=login (Elasticsearch 中的 DocValue)

    https://my.oschina.net/wangfree/blog/77045 (倒排索引)

    相关文章

      网友评论

          本文标题:Elasticsearch 搜索与聚合在数据存储结构方面的理解

          本文链接:https://www.haomeiwen.com/subject/nnnyxftx.html