美文网首页
ElasticSearch 学习笔记

ElasticSearch 学习笔记

作者: ssochi | 来源:发表于2020-10-15 11:00 被阅读0次

    简介

    ES是一款基于Lucene实现的一款分布式搜索引擎,它有以下优点

    • Restful API,接入不需要编程语言支持
    • 数据安全(主从)
    • 功能丰富
    • 接近实施的更新

    Lucene

    Lucene是一个由Java实现的搜索引擎,接下来简要介绍下它的原理

    1.倒排索引

    倒排索引是搜索引擎常用的一种索引方式。
    它十分简单,首先将需要索引的语句进行分词,然后以每个词为key,需要索引的语句为value放入一个"MAP"中.
    这里MAP之所以打引号,是因为我们不去限制这个MAP的实现方法,他可以用任意实现,比如红黑树,hash或者之后会介绍的FST。

    举个例子:
    需要索引的句子:

    1.ElasticSearch 学习笔记
    2.ElasticSearch 牛逼

    倒排索引:

    "ElasticSearch" : [1,2],
    "学习" :[1]
    "笔记" : [1]
    "牛逼" : [2]

    通过倒排索引,我们就能通过单个当词语查询到句子。

    2.FST

    FST全称是Finite State Transducer,
    单从字面上看它类似于有限自动机,但实际可以把它看作一个压缩过但字典树,
    字典树会对词语对前缀进行合并,而FST还会对词语对后缀进行合并。
    我们以mon,thurs,tues三个词为例,
    FST和字典树的结构分别如下:


    字典树
    FST

    优点:内存占用率低,压缩率一般在3倍~20倍之间、模糊查询支持好、查询快
    缺点:结构复杂、输入要求有序、更新不易

    如何构建一个FST?
    1. 将所有的句子按照字典序进行排序
    2. 将句子先按照字典树的方式插入
    3. 如果确定有相同的后缀,则进行链接。
      具体原理可参考:https://www.shenyanchao.cn/blog/2018/12/04/lucene-fst/

    3.怎么存储倒排索引?(猜的)

    一部分缓存在内存,一部分存在硬盘。
    当FST当一个前缀有超过一定数量当后缀则放到内存中,否则存入磁盘。
    真的是这样??

    ES 与 Lucene 当关系

    ES 的结构

    ES是一个分布式服务,它由n个分片和m个备份构成,分片(P)和备份(R)被分配在不同的机器(Node)上,


    ES
    分片

    一个分片里指存储了部分集群信息,具体存哪些则根据文档的routing字段决定(默认就是_id)
    而一个分片上包含以下结构:

    • 多个段(你可以把段理解为倒排索引)
    • commit point,用于找到多个段
    • In-memory buffer,用来收集更新信息
    • transLog,类似与mysql的binLog,用于记录更新操作
    分片
    为什么要有多个段?

    一个段相当于一个Lucene,那为什么要有多个段?
    因为Lucene的倒排索引采用FST实现,FST虽然高效,并且内存利用率高,但是更新困难。因此与其每次花大代价去更新原来的段,不如每次都新建一个段,之后索引时,遍历所有的段,并得出搜索结果。

    但是这样做有两个问题:

    1. 随着段越来越多,搜索的效率会大大降低。
    2. 写入一个新的段需要IO操作,因此如果频繁写入,那么效率底下。

    为了解决问题1,ES启动了一个后台的合并任务,他会在空闲时把这些段合并成一个大段。(类似于LevelDB的level合并机制)
    为了解决问题2,ES使用In-memory buffer在内存中缓存新接受的更新请求。隔一段时间将这些请求整理成一个段,再将这个段放入系统段文件缓存中(注意不立即写入磁盘)。同时将每一个更新操作写入Translog当中,保证数据的持久性。当文件缓存中当段真正被写入磁盘后,清除Translog即可。

    怎样把一个句子存入ES

    首先我们得有一个句子,比如 "ES是=_=世界上最牛逼的搜索引擎",
    ES通过句子的_id找到需要被存储的分片位置,将该句子发送过去,
    之后这个句子会被解析器进行解析。(在ES中有许多解析器,你可以根据需求定义字段对应的解析器)

    1. 首先这个句子首先经过剔除特殊字符的解析器:

    变成 => "ES是世界上最牛逼的搜索引擎"

    1. 经过剔除无用字的解析器:

    变成 => "ES世界牛逼搜索引擎"

    3.经过分词的解析器

    变成 => ['ES','世界','牛逼','搜索','引擎']

    4.经过同义词添加的解析器

    变成 => ['ES','ElasticSearch','世界','牛逼','厉害','狠','搜索','查找','引擎']

    ES将经解析的词和句子做成倒排索引,然后通过上一节所讲的方式存入磁盘。

    如何进行搜索(match)

    这个问题看起来很难,实则很简单。

    1. 首先ES会将输入的句子,通过上一节讲的解析器,分解成多个词。
    2. 将每个词通过倒排索引找到包含的句子
    3. 将这些包含关键词的句子收集起来,通过词语命中次数,命中种类,词频,词权重等进行打分(ES提供了多种打分方法,但是常用的方法是词频/逆向文档频率(term frequency/inverse document frequency)
    4. 将打好分的句子,通过分数排序,然后取前N个返回给用户。

    以上讲解的是对于match方法背后的步骤,当然实际并非这么简单,了解原理就好。
    当然term搜索也是ES中常用的一种搜索方式,它与match不同,他必须精确匹配。ES优化term操作,为它添加了缓存,具体方法就是通过一个稀疏的数组来存储命中的term节点,在将这个数组存入缓存中

    中文分词

    IK 分词器,
    1、词典树Tire Tree的构建,即将现在的词典加载到一个内存结构中去
    2、词的匹配查找,就是切词
    3、歧义判断,即对不同切分方式的判定,哪种应是更合理的

    相关文章

      网友评论

          本文标题:ElasticSearch 学习笔记

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