• 内存吞金兽(Elasticsearch)的那些事儿 -- 写入&检索原理


    协调节点

    客户端写入一条数据,到Elasticsearch集群里边就是由协调节点来处理这次请求:

     

    集群上的每个节点都是coordinating node,表明这个节点可以做路由。比如节点1接收到了请求,但发现这个请求的数据应该是由节点2处理(因为主分片在节点2上),所以会把请求转发到节点2上。

    • coodinate node通过hash算法可以计算出是在哪个主分片上,然后路由到对应的index node
    • shard = hash(document_id) % (num_of_primary_shards)

    节点写入

    • 将数据写到内存缓存区
    • 然后将数据写到translog缓存区
    • 定期将数据从buffer中refresh到FileSystemCache中,生成segment文件,一旦生成segment文件,就能通过索引查询到了
    • refresh完,memory buffer就清空了。
    • 定期将translog 从buffer flush到磁盘中
    • 定期/定量从FileSystemCache中,结合translog内容flush index到磁盘中。

    默认配置运行流程:
    • Elasticsearch会把数据先写入内存缓冲区,然后每隔1s刷新到文件系统缓存区(当数据被刷新到文件系统缓冲区以后,数据才可以被检索到)。所以:Elasticsearch写入的数据需要1s才能查询到
    • 为了防止节点宕机,内存中的数据丢失,Elasticsearch会另写一份数据到日志文件上,但最开始的还是写到内存缓冲区,每隔5s才会将缓冲区的刷到磁盘中。所以:Elasticsearch某个节点如果挂了,可能会造成有5s的数据丢失。
    • 等到磁盘上的translog文件大到一定程度或者超过了30分钟,会触发commit操作,将内存中的segment文件异步刷到磁盘中,完成持久化操作。

    说白了就是:写内存缓冲区(定时去生成segment,生成translog),能够让数据能被索引、被持久化。最后通过commit完成一次的持久化。

    最后

    等主分片写完了以后,会将数据并行发送到副本集节点上,等到所有的节点写入成功就返回ack给协调节点,协调节点返回ack给客户端,完成一次的写入。

    更新和删除

    • 给对应的doc记录打上.del标识,如果是删除操作就打上delete状态,如果是更新操作就把原来的doc标志为delete,然后重新新写入一条数据
    • 前面提到了,每隔1s会生成一个segment 文件,那segment文件会越来越多越来越多。Elasticsearch会有一个merge任务,会将多个segment文件合并成一个segment文件。在合并的过程中,会把带有delete状态的doc物理删除掉。

    检索原理 

    核心

    link:3. 数据结构

    两大类

    es的检索主要分为两大类

    1. 根据ID查询doc(实时)
      1. 检索内存的Translog文件
      2. 检索硬盘的Translog文件
      3. 检索硬盘的Segment文件
    2. 根据query(搜索词)去查询匹配的doc(近实时,因为segment文件是每隔一秒才生成一次的)
      1. 查询Segment

    三阶段

    • QUERY_AND_FETCH(查询完就返回整个Doc内容)

    • QUERY_THEN_FETCH(先查询出对应的Doc id ,然后再根据Doc id 匹配去对应的文档)

    • DFS_QUERY_THEN_FETCH(先算分,再查询)

      • 「这里的分指的是 词频率和文档的频率(Term Frequency、Document Frequency)众所周知,出现频率越高,相关性就更强」

     


    一般我们用得最多的就是QUERY_THEN_FETCH,第一种查询完就返回整个Doc内容(QUERY_AND_FETCH)只适合于只需要查一个分片的请求。

    QUERY_THEN_FETCH总体的大概流程流程:

    • 客户端请求发送到集群的某个节点上。集群上的每个节点都是coordinate node(协调节点)
    • 然后协调节点将搜索的请求转发到所有分片上(主分片和副本分片都行)
    • 每个分片将自己搜索出的结果(doc id)返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果。
    • 接着由协调节点根据 doc id 去各个节点上拉取实际的 document 数据,最终返回给客户端。

    Query Phase阶段时节点做的事:

    • 协调节点向目标分片发送查询的命令(转发请求到主分片或者副本分片上)
    • 数据节点(在每个分片内做过滤、排序等等操作),返回doc id给协调节点

    Fetch Phase阶段时节点做的是:

    • 协调节点得到数据节点返回的doc id,对这些doc id做聚合,然后将目标数据分片发送抓取命令(希望拿到整个Doc记录)
    • 数据节点按协调节点发送的doc id,拉取实际需要的数据返回给协调节点
    (C) 房上的猫 。 保留所有权利。 https://www.cnblogs.com/lsy131479/ 如需转载,请注明出处!!!
  • 相关阅读:
    Android代码执行adb shell top命令读取结果
    Android8.0+跨应用发送广播和跨应用启动前台服务
    Android代码执行adb shell命令
    关于参数获取的那些事儿
    c# 如何处理自定义消息
    esp32 mqtt协议上报 dht11温湿度数据到onenet 指令下发控制开关灯
    swoole-simps自搭mqtt服务器,完美实现订阅,发布并存到mysql
    stm32f103c8t6+esp8266+dht11 mqtt上传温湿度到阿里云
    使用ST-Link下载程序出现Error:Flash Download Failed-“Cortex-M3“ 解决详细步骤(附图)
    stm32f407 oled iic例程,成功点亮oled屏
  • 原文地址:https://www.cnblogs.com/lsy131479/p/15184408.html
Copyright © 2020-2023  润新知