作者:刘晓国
Elasticsearch 通常允许你快速搜索大量数据。 在某些情况下,搜索可能在许多 shard 上执行,可能针对 frozen indices (冻结的索引)及跨越多个远程集群 (remote clusters),因此预期结果不会在毫秒内返回。 当你需要执行长时间运行的搜索时,同步等待返回结果是不理想的。 相反,异步搜索使你可以提交异步执行的搜索请求,监视请求的进度,并在以后的阶段检索结果。 你也可以在部分结果可用时但在搜索完成之前检索它们。
你可以使用提交异步搜索 API 提交异步搜索请求。 使用 get async search API,你可以监视异步搜索请求的进度并检索其结果。 正在进行的异步搜索可以通过 Delete async search API 删除。
Async search
异步搜索 API 使您可以异步执行搜索请求,监视其进度以及在部分结果可用时检索它们。
提交 async search API
异步执行搜索请求。 它接受与 Search API 相同的参数和请求正文。
POST /sales*/_async_search?size=0 { "sort": [ { "date": { "order": "asc" } } ], "aggs": { "sale_date": { "date_histogram": { "field": "date", "calendar_interval": "1d" } } } }
该响应包含正在执行的搜索的标识符。 你可以使用此 ID 稍后检索搜索的最终结果。 当前可用的搜索结果作为 response 对象的一部分返回。
{ "id" : "FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=", (1) "is_partial" : true, (2) "is_running" : true, (3) "start_time_in_millis" : 1583945890986, "expiration_time_in_millis" : 1584377890986, "response" : { "took" : 1122, "timed_out" : false, "num_reduce_phases" : 0, "_shards" : { "total" : 562, (4) "successful" : 3, (5) "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 157483, (6) "relation" : "gte" }, "max_score" : null, "hits" : [ ] } } }
1.异步搜索的标识符,可用于监视其进度,检索其结果和/或将其删除
2.当查询不再运行时,指示在所有分片上搜索是失败还是成功完成。 在查询正在被执行时,is_partial 始终设置为 true
3.搜索是仍在执行还是已完成
4.总体上将对多少个分片执行搜索
5.有多少碎片已成功完成搜索
6.当前有多少文件与查询匹配,属于已经完成搜索的分片
注意:尽管查询不再运行,因此 is_running 设置为 false,但结果可能是不完整的。 如果某些分片返回结果后搜索失败,或者协调异步搜索的节点死亡,就会发生这种情况。
通过提供 wait_for_completion_timeout 参数(默认为1秒),可以阻止并等待直到完成某个超时为止的搜索。 当异步搜索在此超时内完成时,响应将不包含 ID,因为结果不存储在集群中。 可以将 keep_on_completion 参数(默认为 false)设置为true,以请求存储结果以供以后检索,也可以在 wait_for_completion_timeout 内完成搜索时使用。
你还可以通过 keep_alive 参数(默认为5d,即五天)指定需要进行多长时间的异步搜索。 在此期间之后,正在进行的异步搜索和所有保存的搜索结果将被删除。
注意:当结果的主要排序是一个被索引字段时,分片将根据它们对该字段持有的最小值和最大值进行排序,因此,可以根据请求的排序标准获得部分结果。
提交异步搜索 API 支持与 Search API 相同的参数,尽管有些参数具有不同的默认值:
1.batched_reduce_size 的默认值为5:这会影响部分结果可用的频率,每当分片结果减少时就会发生这种情况。 每次协调节点收到一定数量的新分片响应(默认为5个)时,都会执行部分减少。
2.request_cache 默认为 true
3.pre_filter_shard_size 的默认值为1,并且不能更改:这是为了强制执行一次预过滤器往返操作以从每个分片中检索统计信息,从而使那些肯定不保存与查询匹配的文档的数据被跳过。
4.ccs_minimize_roundtrips 默认为 false,这也是唯一受支持的值
警告:异步搜索不支持滚动或仅包含建议部分的搜索请求。 仅当 ccs_minimize_roundtrips 设置为 false 时,才支持跨集群搜索。
获取 async search
给定其 ID,获取 async search API 会检索先前提交的异步搜索请求的结果。 如果启用了 Elasticsearch 安全功能。 特定异步搜索结果的访问仅限于首先提交它的用户。
GET /_async_search/FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=
{ "id" : "FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=", "is_partial" : true, (1) "is_running" : true, (2) "start_time_in_millis" : 1583945890986, "expiration_time_in_millis" : 1584377890986, (3) "response" : { "took" : 12144, "timed_out" : false, "num_reduce_phases" : 46, (4) "_shards" : { "total" : 562, (5) "successful" : 188, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 456433, "relation" : "eq" }, "max_score" : null, "hits" : [ ] }, "aggregations" : { (6) "sale_date" : { "buckets" : [] } } } }
1.当查询不再运行时,指示在所有分片上搜索是失败还是成功完成。在执行查询时,is_partial 始终设置为 true
2.搜索是仍在执行还是已完成
3.异步搜索何时到期
4.指示执行了多少次结果缩减。如果该数字与上次检索到的结果相比有所增加,则可以预期搜索结果中将包含更多的结果
5.指示有多少个 shard 执行了查询。请注意,为了将 shard 结果包含在搜索响应中,需要首先减少 shard 结果。
6.来自已经完成查询执行的分片的部分聚合结果。
在调用 Get Async Search API 时,也可以提供 wait_for_completion_timeout 参数,以等待搜索完成直到提供的超时。如果超时到期,将返回最终结果(如果有),否则超时到期后将返回当前可用的结果。默认情况下,未设置超时,这意味着将返回当前可用的结果,而无需任何额外的等待。
keep_alive 参数指定异步搜索在集群中应可用的时间。如果未指定,将使用带有相应的提交异步请求的 keep_alive 集。否则,可以覆盖该值并扩展请求的有效性。该时间段到期后,如果仍在运行,则取消搜索。如果搜索完成,则其保存的结果将被删除。
删除 async search
你可以使用 Delete async search API 来按 ID 手动删除异步搜索。 如果搜索仍在运行,搜索请求将被取消。 否则,将删除保存的搜索结果。
DELETE /_async_search/FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=
参考
【1】 https://www.elastic.co/guide/en/elasticsearch/reference/master/async-search.html