ES scroll search原理

一、 ES搜索两阶段简介

ES的搜索是分2个阶段进行的,即Query阶段和Fetch阶段。 

Query阶段比较轻量级,通过查询倒排索引,获取满足查询结果的文档ID列表。 

Fetch阶段比较重,需要将每个shard的结果取回,在协调结点进行全局排序。  通过From+size这种方式分批获取数据的时候,随着from加大,需要全局排序并丢弃的结果数量随之上升,性能越来越差。
 

二、 scroll分析
Scroll查询,先做轻量级的Query阶段以后,免去了繁重的全局排序过程。 它只是将查询结果集,也就是doc id列表保留在一个上下文里, 之后每次分批取回的时候,只需根据设置的size,在每个shard内部按照一定顺序(默认doc_id续), 取回这个size数量的文档即可。 
 

三、 scroll使用场景
可以看出scroll不适合支持那种实时的和用户交互的前端分页工作,其主要用途用于从ES集群分批拉取大量结果集的情况,一般都是offline的应用场景。  比如需要将非常大的结果集拉取出来,存放到其他系统处理,或者需要做大索引的reindex等等。

游标查询 Scroll

scroll 查询 可以用来对 Elasticsearch 有效地执行大批量的文档查询,而又不用付出深度分页那种代价。

游标查询允许我们 先做查询初始化,然后再批量地拉取结果。 这有点儿像传统数据库中的 cursor 。

游标查询会取某个时间点的快照数据。 查询初始化之后索引上的任何变化会被它忽略。 它通过保存旧的数据文件来实现这个特性,结果就像保留初始化时的索引 视图 一样。

深度分页的代价根源是结果集全局排序,如果去掉全局排序的特性的话查询结果的成本就会很低。 游标查询用字段 _doc 来排序。 这个指令让 Elasticsearch 仅仅从还有结果的分片返回下一批结果。

启用游标查询可以通过在查询的时候设置参数 scroll 的值为我们期望的游标查询的过期时间。 游标查询的过期时间会在每次做查询的时候刷新,所以这个时间只需要足够处理当前批的结果就可以了,而不是处理查询结果的所有文档的所需时间。 这个过期时间的参数很重要,因为保持这个游标查询窗口需要消耗资源,所以我们期望如果不再需要维护这种资源就该早点儿释放掉。 设置这个超时能够让 Elasticsearch 在稍后空闲的时候自动释放这部分资源。

GET /old_index/_search?scroll=1m 
{
    "query": { "match_all": {}},
    "sort" : ["_doc"], 
    "size":  1000
}

 

保持游标查询窗口一分钟。

 

关键字 _doc 是最有效的排序顺序。

这个查询的返回结果包括一个字段 _scroll_id, 它是一个base64编码的长字符串 。 现在我们能传递字段 _scroll_id 到 _search/scroll 查询接口获取下一批结果:

GET /_search/scroll
{
    "scroll": "1m", 
    "scroll_id" : "cXVlcnlUaGVuRmV0Y2g7NTsxMDk5NDpkUmpiR2FjOFNhNnlCM1ZDMWpWYnRROzEwOTk1OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MTA5OTM6ZFJqYkdhYzhTYTZ5QjNWQzFqVmJ0UTsxMTE5MDpBVUtwN2lxc1FLZV8yRGVjWlI2QUVBOzEwOTk2OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MDs="
}

 

注意再次设置游标查询过期时间为一分钟。

这个游标查询返回的下一批结果。 尽管我们指定字段 size 的值为1000,我们有可能取到超过这个值数量的文档。 当查询的时候, 字段 size 作用于单个分片,所以每个批次实际返回的文档数量最大为 size * number_of_primary_shards 。

注意游标查询每次返回一个新字段 _scroll_id。每次我们做下一次游标查询, 我们必须把前一次查询返回的字段 _scroll_id 传递进去。 当没有更多的结果返回的时候,我们就处理完所有匹配的文档了。

参考:Elasticsearch之SearchScroll原理剖析和优化

elasticsearch scroll查询原理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Elasticsearch scroll 查询是一种用于处理大型数据集合的技术。它允许您在不影响性能的情况下,逐步地检索大量的搜索结果。 以下是一个基本的scroll查询的示例: ``` POST /my_index/_search?scroll=1m { "size": 100, "query": { "match" : { "title" : "elasticsearch" } } } ``` 在上面的查询中,我们指定了一个初始搜索请求,并将scroll参数设置为1分钟。我们还指定了一个"size"参数,该参数指定了每个批次要返回的文档数。在此示例中,我们将每个批次的文档数设置为100。 当我们运行此查询时,Elasticsearch将返回一个初始的搜索结果集,并为我们提供一个scroll_id。我们可以使用此scroll_id执行后续的搜索请求,以逐步检索结果。 以下是一个使用scroll_id执行后续搜索请求的示例: ``` POST /_search/scroll { "scroll": "1m", "scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVRMNGxKUXE2Z2lKSEFZa1VUQQ==" } ``` 在上面的查询中,我们指定了一个scroll_id参数,该参数包含之前搜索请求返回的scroll_id。我们还将scroll参数设置为1分钟,以便Elasticsearch知道我们要继续检索结果。 使用scroll查询时,需要注意以下几点: 1. 每个scroll查询请求都会消耗一些系统资源,因此不应该无限制地使用它。 2. 一旦您完成了scroll查询,您应该及时清除scroll上下文,以释放资源。 3. 如果您的查询需要对大量文档进行排序,scroll查询可能不是最佳选择。排序会增加查询的内存使用量,从而增加查询的资源消耗。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值