Elasticsearch GET 流程
  TEZNKK3IfmPf 2023年11月14日 44 0

ES的读取分为GET和Search两种操作,这两种读取操作有较大的差异,GET/MGET必须指定三元组:_index、_type、_id。也就是说,根据文档id从正排索引中获取内容。而Search不指定_id,根据关键词从倒排索引中获取内容。本章分析GET/MGET过程,下一章分析Search过程。

一个GET请求的简单例子(来自官网)如下:

curl -XGET http://127.0.0.1:9200/website/blog/1?pretty
{
    "_index":"website",
    "_type":"blog",
    "_id":"1",
    "_version":21,
    "found":true,
    "_source":{
        "first_name":"John",
        "last_name":"Smith",
        "age":25,
        "about":"I love to go rock climbing",
        "interests":[
            "sports",
            "music"
        ]
    }
}

1、可选参数

与写请求相同,GET请求时可以在URI中设置一些可选参数,如下表所示:
Elasticsearch  GET 流程

2、GET基本流程

搜索和读取文档都属于读操作,可以从主分片或副分片中读取数据。
读取单个文档的流程(图片来自官网)如下图所示:
Elasticsearch  GET 流程

这个例子中的索引有一个主分片和两个副分片。以下是从主分片或副分片中读取时的步骤:

  1. 客户端向NODE1发送读请求。
  2. NODE1使用文档ID来确定文档属于分片0,通过集群状态中的内容路由表信息获知分片0有三个副本数据,位于所有的三个节点中,此时它可以将请求发送到任意节点,这里它将请求转发到NODE2。
  3. NODE2将文档返回给 NODE1,NODE1将文档返回给客户端。NODE1作为协调节点,会将客户端请求轮询发送到集群的所有副本来实现负载均衡。

在读取时,文档可能已经存在于主分片上,但还没有复制到副分片。在这种情况下,读请求命中副分片时可能会报告文档不存在,但是命中主分片可能成功返回文档。一旦写请求成功返回给客户端,则意味着文档在主分片和副分片都是可用的。

3、GET详细分析

GET/MGET流程涉及两个节点:协调节点和数据节点,流程如下图所示:
Elasticsearch  GET 流程

3.1 协调节点

执行本流程的线程池:http_server_worker。
TransportSingleShardAction 类用来处理存在于一个单个(主或副)分片上的读请求。将请求转发到目标节点,如果请求执行失败,则尝试转发到其他节点读取。

3.2 数据节点(略)

4、MGET流程分析

MGET 的主要处理类:TransportMultiGetAction,通过封装单个GET 请求实现,处理流程如下图所示:
Elasticsearch  GET 流程

主要流程如下:

  1. 遍历请求,计算出每个doc的路由信息,得到由shardid为key组成的request map。这个过程没有在TransportSingleShardAction中实现,是因为如果在那里实现,shardid就会重复,这也是合并为基于分片的请求的过程。
  2. 循环处理组织好的每个 shard 级请求,调用处理 GET 请求时使用 TransportSingleShardAction#AsyncSingleAction处理单个doc的流程。
  3. 收集Response,全部Response返回后执行finishHim(),给客户端返回结果。

回复的消息中文档顺序与请求的顺序一致。如果部分文档读取失败,则不影响其他结果,检索失败的doc会在回复信息中标出。

5、思考

我们需要警惕实时读取特性,GET API默认是实时的,实时的意思是写完了可以立刻读取,但仅限于GET、MGET操作,不包括搜索。在5.x版本之前,GET/MGET的实时读取依赖于从translog中读取实现,5.x版本之后的版本改为refresh,因此系统对实时读取的支持会对写入速度有负面影响。

由此引出另一个较深层次的问题是,update操作需要先GET再写,为了保证一致性,update调用GET时将realtime选项设置为true,并且不可配置。因此update操作可能会导致refresh生成新的Lucene分段。

读失败是怎么处理的? 尝试从别的分片副本读取。
优先级 优先级策略只是将匹配到优先级的节点放到了目标节点列表的前面

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月14日 0

暂无评论

推荐阅读
TEZNKK3IfmPf