美文网首页
分布式搜索和分析

分布式搜索和分析

作者: 上山走18398 | 来源:发表于2019-10-30 11:50 被阅读0次

    简介

    keyword:
    lucene
    全文检索:顺序扫描法、全文检索(非结构化数据->带索引的结构化数据,一次索引创建,多次使用)
    elastic search
    solr
    创建倒排索引 -> 定位到文档
    分词、索引、类型、文档、分布式
    参考链接:
    https://blog.csdn.net/zhangdefeng2008/article/details/79591481 有对比
    https://es.xiaoleilu.com/010_Intro/00_README.html 教程
    https://blog.csdn.net/qq_15958689/article/details/79526784 分片概念

    • 常用搜索引擎
    1. Lucene

    Lucene是Apache发布的一个开放源代码的全文搜索引擎工具包,是一个全文检索引擎架构,提供了完整的创建索引查询索引,以及部分文本分析的引擎

    工作原理:

    gateher data => Document(生成文档) => Index(做索引库) => Analyze(分词器)_打标签提高精准度
    user  <=> query <=>  search index
    
    全文搜索技术,绝大数是基于倒排索引来做;
    词典+倒排表
    

    Lucene是根据关键字来搜索的文本搜索工具,只能在某个网站内部搜索文本内容,不能跨站搜索
    参考链接:https://blog.csdn.net/njpjsoftdev/article/details/54015485

    1. Elasticsearch

    通过简单 restful API来隐藏Lucene的复杂性,从而让全文搜索变得简单
    分布式以支持海量的数据
    实时分析
    分布式的实时文件存储,每个字段都被索引并可被搜索
    正排索引:文档id到单词的关联关系 -> 文档中找字符串
    倒排索引:单词到文档id的关联关系 -> 字符串找文档
    倒排索引组成: 单词词典(B+树)_便于快速搜索到某个term 倒排列表(单词对应的文档集合)
    ES存储的是一个JSON格式的文档,其中包含多个字段,每个字段会有自己的倒排索引

    1. solr

    Solr索引的实现方法很简单,用Post向solr服务器发送一个描述Field及其内容的XML文档,Solr根据xml文档添加、删除、更新索引。然后对solr返回对xml,json等格式的查询结构进行解析,组织页面布局
    对已有数据搜索时更快,当建立索引时,solr会产生io阻塞,查询性能差
    随着数据量的增长,Solr的搜索效率会变得更低,而es没有明显变化

    对比

    solr利用zk进行分布式管理,而ES自带
    solr支持更多的格式,es只支持json
    处理实时搜索效率es更强
    es建立索引快

    Elastic Search

    关键字

    分词->倒排索引 (倒排索引一旦创建,不可更改,带来的好处)
    压缩
    搜索引擎原理:爬取内容 -> 进行分词 -> 就是建立反向索引
    https://blog.csdn.net/u011635492/article/details/81023158 对于倒排过程比较细致,为什么比mysql B+树的检索速度快

    1. 专有名词:
      索引(数据库) 、
      类型(表)、
      文档(行)、
      Term(项-某列的具体值,也可能是Field下面的值分词之后的词元)、
      Analyzer(分析器) + Tokenizer(分词器) + TokenFilters(词过滤器)
      >全文搜索引擎对文档进行分析,首先通过Tokenizer得到token(切词处理),token通过token filter(停顿词过滤)获得Term > 小写分词器、空格分词器 模式分词器 合并词(Document Frequency,出现在所有文档的总数) > 将得到的词交给索引组件
      Segment:
      1、 lucene将一个大大逆向索引拆分成多个小段segment。每个segment本质上就是一个倒排索引
      2、lucene维护一个文件commit point,记录当前所有可用的segment,当在commit point上进行搜索时,相当于在它下面的segment中进行搜索,汇总再返回给用户
      3、 每个commit point都维护一个.del文件,文件内记录了在某个segment内某个文档已经被删除,但是在segment中依然可以被搜索到,不过在返回之前,会根据.del的内容过滤掉
      文档的更新,类似。首先在.del文件中声明这个文档已经被删除,同时新的文档会被存到一个新的segment。 tranlog防止丢失后
      Refresh: 近乎实时搜索,fsync操作确保写入磁盘成功, segment(先收集到indexing buffer)写入文件系统缓存(也可以被读取),未写入磁盘,在文件缓存中就可以读取segment
      在es中,将缓存中的文档写入segment,并打开segment使之可以被搜索到过程叫做refresh(默认情况,分片的refresh时1次/s),
      一条新写入的数据在refresh之前是搜索不到的
      index.refresh_inteval:100s
      倒排索引 建立 更新 删除

    Shard (分片)最小级别的工作单元,保存索引中所有数据的一小部分,一个分片就是一个lucene实例,
    主分片和复制分片
    分布机制:https://blog.csdn.net/xiaocai9999/article/details/80561639 好理解
    文档存储在分片中,并且在分片中被索引

    索引
    poems
    类型
    "poem":{
      "properties":{
        "title":{
          "type":"keyword",   //keyword类型不会分词,直接根据字符串内容建立反向索引
    },
         "author":{
          "type":"keyword",
    }
         "dynasty":{
          "type":"keyword",
    },
          "words":{
          "type":"keyword",
    },
    "content":{
          "type":"text", // text类型存入es的时候,会先分词,然后根据分词后的内容建立反向索引
          },
        }
    }
    
    文档
    {
    "title":"静夜思",
    "author":"李白",
    "dynasty":"唐",
    "words":"20",
    "content":"床前明月光,疑是地上霜,举头望明月,低头思故乡",
    }
    类型相当于表结构的描述,描述每个字段的类型
    文档已json形式描述以一行数据
    => 存入elastic search
    调用API
    
    elastic 分布式原理
    es集群可以包含多个索引(indices)
    每个索引可以包含多个类型(types)
    每个类型可以包含多个文档(documents)
    每个文档包含多个字段(Fields)
    elasticsearch会对数据进行切分,同时每一个分片会保存多个副本保证高可用性
    master-slave
    增删改查
    建立索引和写入需要经过master,
    数据的写入有一个简单的routing规则,可以route到集群中的任意节点(协调节点),所以数据写入压力是分散在整个集群的
    
    

    Shard(分片):
    一个lucene实例 一个节点可以包含多个分片
    一个索引的所有数据时分布在所有主分片上的 主分片又分布在不同节点
    主分片和复制分片,主分片写完,同步到副分片上,等所有分片写完才会成功
    文档存在分片中(文档_id),并且在分片中被索引

    分布式搜索

    1. 客户端发送一个search(搜索)请求, 请求给Node(随机轮询算法),这个node创建了一个长度为from+size的空优先级队列
    2. Node 转发这个搜索请求到索引中每个分片的原本或副本,每个分片在本地执行这个查询并且将结果到一个大小为from+size的有序本地优先队列里
    3. 每个分片返回document的ID和它优先队列里的所有document的排序值给协调节点Node,node把这些值合并到自己的优先队列里产生全局排序结果

    elk系统: elasticsearch + logstash + kibana
    实时计算模块:
    https://blog.csdn.net/u010454030/article/details/75986072
    Free Maker模版引擎
    elasticsearch-head查看

    面试:https://blog.csdn.net/abcd1101/article/details/89010070
    深分页问题:https://blog.csdn.net/weixin_40341116/article/details/80821655

    实战:

    ElasticsearchTemplate 、 TransportClient
    
    BoolqueryBuilder: termQuery matchQuery filter must should
    term搜索时不分词,match搜索时分词
    query和filter:query context会进行相关性算分,有_score返回;filter不会进行相关性算分
    rangeQuery
    
    SortBuilder:
      FieldSortBuilder; 属性值排序,按某个字段进行排序
      GeoDistanceSortBuilder:根据地理位置排序
      ScoreSortBuilder: 根据score排序
      ScriptSortBuilder: 根据自定义脚本排序
    
    SearchRequestBuilder
      SearchType: dfs_query_then_fetch query_then_fetch .......
      .setSize() 
      .setPreference //每次都查询主分片,防止多次查询结果不一致
      .setFrom() //分页
      .setScroll()  //此处容易引发问题?
    SearchResponseBuilder
      
      SearchHit
    10000  深分页问题
    获取分词结果 ikRequest 调用es获取ik 分词结果 -> 对结果做筛选,如热点文案
    

    深分页问题:

    分页越深则越容易OOM,即便不OOM,也很消耗CPU和内存资源
    Es为了避免深分页,不允许使用(from&size)查询10000条以后的数据,因此如果要查询第10000条以后的数据,要使用ES提供的scroll(游标)来查询
    index.max_result_window:10000作为保护措施

    相关文章

      网友评论

          本文标题:分布式搜索和分析

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