• ES分布式搜索引擎架构原理


    ES是啥?

    ES就是一个开源的搜索引擎    也是一个分布式文档数据库

    可以在极短的时间内存储、搜索和分析大量的数据。

    ES基本属性:

    字段

    ES中,每个文档,其实是以json形式存储的。而一个文档可以被视为多个字段的集合。

    映射

    每个类型中字段的定义称为映射。例如,name字段映射为String。

    索引

    索引是映射类型的容器。 一个ES的索引非常像关系型世界中的数据库,是独立的大量文档集合

    ES各属性对应关系数据库

    关系数据库 ->   表名                ->  表结构    ->  一条记录       -> 一个字段

    ES        -> 索引index - 类型type(1-n) -> 映射apping  ->  文档document  -> 字段field 

    ES索引简单原理: 采用倒排索引

    Term(单词):一段文本经过分析器分析以后就会输出一串单词,这一个一个的就叫做Term

    Term Dictionary(单词字典):顾名思义,它里面维护的是Term,可以理解为Term的集合

    Term Index(单词索引):为了更快的找到某个单词,我们为单词建立索引

    Posting List(倒排列表):以前是根据ID查内容,倒排索引之后是根据内容查ID,然后再拿着ID去查询出来真正需要的东西。

    如果类比现代汉语词典的话,那么Term就相当于词语,Term Dictionary相当于汉语词典本身,Term Index相当于词典的目录索引)

    通过 单词索引 找到单词在单词字典中的位置,通过单词字典进而找到Posting List倒排列表,有了倒排列表就可以根据ID找到文档.

    (本质:通过单词找到对应的倒排列表,根据倒排列表中的倒排项进而可以找到文档记录)

    查询结果分析:

    took:本次操作花费的时间,单位为毫秒。

    timed_out:请求是否超时

    _shards:说明本次操作共搜索了哪些分片

    hits:搜索命中的记录

    hits.total : 符合条件的文档总数 hits.hits :匹配度较高的前N个文档

    hits.max_score:文档匹配得分,这里为最高分

    _score:每个文档都有一个匹配度得分,按照降序排列。

    _source:显示了文档的原始内容。

    ES聚合

    桶在概念上类似于 SQL 的分组(GROUP BY),而指标则类似于 COUNT() 、 SUM() 、 MAX() 等统计方法

    ES分布式架构原理

    shard就是ES索引存储具体数据的地方,一个索引对应多个shard

    多个shard存储在不同的机器上

    每个shard只放索引的一部分数据

    每个shard的副本replic放在其他机器上(shard的主体primary和副本replic分开存) 保证了一定程度的高可用

    ES写入数据原理:

    从客户端写入到shard的全过程:

    1. 客户端随机找一个ES集群节点当作协调节点,写数据
    2. 协调节点将数据 根据doc id的哈希路由,写入分配的shard并同步到从shard
    3. shard将数据写入内存buffer
    4. 内存buffer每一秒钟refresh一次将数据刷进OScache缓存,一份sagementfile,一份translog日志 (translog日志的作用 有点类似于redis的RDB文件,用于ES宕机恢复数据)  
    5. OScache缓存每5秒中刷入磁盘的translog日志文件
    6. 每30分钟执行一次flush操作,执行一次commit,强制将内存buffer和OScache数据刷入新创建一个sagmentfile文件(磁盘) 落地到磁盘,多个sagementfile会有merge操作。

     数据搜索主要是从OScache中拿的,所以刚写入shard的数据要一秒后才能读到。

    写入一条document数据时会产生一个doc id,查的时候根据doc id进行哈希,路由到对应的shard  (doc id默认随机分配,也可以手动指定,例如订单id)

     

    ES删除数据原理:

    1.把被删除数据写入.del文件(磁盘),被.del文件标识的被认为已删除

    2.当sagmentfile文件过多时ES会产生merge操作,将多个segmentfile合成一个,如果.del标识了删除的数据 merge后不会产生在新的segmentfile.

     

     

    ES根据doc id读取数据过程:

    选ES集群的任一台机器当作协调节点

    协调节点根据要查找的doc id 哈希路由到对应的节点的shard,

    查到结果返还给协调节点,协调节点返还给客户端。

     

     

    ES检索数据过程:

    客户端发送读取请求到任一台机器当作协调节点,协调节点发送给所有机器所有shard,

    每个shard都会返回结果,协调节点拿到所有shard返回的匹配的结果,再次筛选最匹配的那些document,返还给客户端.

    每次查询完都会暂时将数据存入cache中,再次

     

     

    ES在数据量很大的情况下如何优化查询(保证搜索性能):

    主要思想:最大限度利用cache的高效率进行查询(磁盘查询效率太低)

    (1) 合理利用ES+Hbase/MySQL结合来查询(Hbase对海量数据在线存储)

    把重要的检索字段存成ES索引 (例如gid,订单id,订单金额,订单时间,订单说明...)

    其余不作为检索条件的字段存在Hbase/Mysql

    用ES根据条件快速查出gid

    再用gid去Hbase/MySQL查出全部字段

    (2) 数据预热

    每隔一段时间将热门关键数据写个程序去查一下,主动从磁盘写入到cache中

    (3) 冷热分离

    水平拆分,将很热的数据单独写进一个索引,将冷数据热数据拆成两个单独索引,放在不同机器上。

    (5) 单索引查,不要join多个索引查,效率非常低 (想办法导入ES的时候直接将要Join的表直接导成一个索引)

    (4) 分页性能 (深度分页,性能越差)

    查第100页的10条数据/第1001-1010,由于ES分布式的存储,必须去每台机器每个shard都查1000条,全部返回到协调节点,合并排序后再取出1001-1010。

    解决:合理利用Scroll游标

    scroll会一次性获取所有数据的快照,每次翻页通过游标移动获取下一页,分页性能大很多。、

    scroll不能乱跳,只能顺序向下翻

     

     

    ES生产集群部署架构

    模板:每个索引的数据大概有多少,每个索引大概分多少shard

    ES集群部署5台机器,每台6核64G,总内存320G,分8个shard

    ES集群每天增量2000万条,大约500M,每月大约6亿条 15G数据

  • 相关阅读:
    mvn地址
    .net 通过蓝牙调用佳博标签打印机
    DockerDesktop使用自带的k8s v1.24.0 使用kubectl获取不到token的问题
    ubuntu firefox install video code
    发送消息的方式在enum中指定
    6pom里配置阿里云仓库
    7idea 手动配置运行 spring 项目
    10idea手动配置run vue
    9写一个最简单的测试接口
    2VUE布局
  • 原文地址:https://www.cnblogs.com/liliuguang/p/14478270.html
Copyright © 2020-2023  润新知