elasticsearch的ScanScroll如何使用

71次阅读
没有评论

共计 2561 个字符,预计需要花费 7 分钟才能阅读完成。

这篇文章主要讲解了“elasticsearch 的 ScanScroll 如何使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着丸趣 TV 小编的思路慢慢深入,一起来研究和学习“elasticsearch 的 ScanScroll 如何使用”吧!

ScanScroll 的特点

优点

速度快

大数据量

缺点

不支持排序

不支持分页

不支持评分

不支持续查

使用场景

  看起来,缺点要比优点多很多,不过它很有用。如果说 BULK 是为了快速入库存在的,那 SCAN 就是为了快速出库而诞生的。ES 的查询性能优越,但是分析能力弱。所以会有, 比如把 ES 的数据拉到 Hadoop 集群去分析计算的需求,当然这个已经有现成的插件了,不出所料也是用的 SCAN。如果 SCAN 遭遇 BULK,也就是 ES 到 ES 的话,它有另一个更熟悉的名字叫 复制表。

使用方法

def scanTest():
 searchRes = es.search(index= users ,size=10,body={ query : { match_all : {}}},search_type= scan ,scroll= 10s )
 while True:
 scrollRes=es.scroll(scroll_id=searchRes[ _scroll_id],scroll= 10s ,ignore=[400, 404])
 res_list = scrollRes[hits][hits]
 if not len(res_list):
 break;
 for res in res_list:
 print res[_source][userName]

原理流程

  整个流程比较清晰,先 count 一个总数,下面每次 scroll,返回 size* 分片数的数据,直到遍历全部。SCAN 是支持查询偏好 preference 的,可以指定分片,所以有人说的 size* 主分片数,是不准确的,这个很容易验证。

第一阶段:Search

用 TotalHitCountCollector 统计下总数,并且确定(节点,查询上下文 ID),Base64 编码成 ScrollId 返回

第二阶段:SearchScroll

根据 ScrollId 去每个节点,找到查询上下文 ID 执行 XFilteredQuery,收集结果,合并返回

  第一阶段除了返回总数,还有一个很神秘的 ScrollId,这个 ScrollId 长成这样,很像 Base64 编码过的。一定不是 ID 那么简单,了解一番,果不其然  ,主要有 3 个部分组成 type,context,attributes

type 分别是 queryThenFetch,queryAndFetch,scan, 我们这里讲的是 scan

attributes 只有一个元素,total_hits

context 是个分片的元组,有 2 个元素,分片 = [节点 ID, 查询上下文 ID]

 ScrollId 是个很容易会暴露秘密的东西,我们会发现 ScrollId 依赖的节点 ID 和查询上下文 ID 都是变量,查询上下文 ID,每次请求都要递增的。所以每次请求的 ScrollId 都不一样,导致了如果在我们的 SCAN 过程意外终止,我们可能需要重新来过。

  每次 SCAN,处理 Scroll 跳到下一页去,我们自己指定 form 是无效的。

//SearchService
private void processScroll(InternalScrollSearchRequest request, SearchContext context) {
 // process scroll
 context.from(context.from() + context.size());
 context.scroll(request.scroll());
 // ...
 }
//ScanContext
public TopDocs execute(SearchContext context) throws IOException { ScanCollector collector = new ScanCollector(readerStates, context.from(), context.size(), context.trackScores());
 Query query = new XFilteredQuery(context.query(), new ScanFilter(readerStates, collector));
 try { context.searcher().search(query, collector);
 } catch (ScanCollector.StopCollectingException e) {
 // all is well
 }
 return collector.topDocs();}

  自定义的 Filter,Collector,执行搜索,收集那一页的结果集

 //ScanContext
 public void collect(int doc) throws IOException { if (counter  = from) { docs.add(new ScoreDoc(docBase + doc, trackScores ? scorer.score() : 0f));
 }
 readerState.count++;
 counter++;
 if (counter  = to) {
 throw StopCollectingException;
 }
}

  根据以往数据库的认识,count 操作总是很慢的,这让我很担心会延长整个查询的时间,后来我发现这种担心是多余的,对于全文检索 count 操作是很快速的。根据测试,17 亿数据 24 个分片,平均每个分片的 count 时间在 200ms 到 700ms 之间,最糟糕的情况下总数也能在 1 秒内返回,这对于整个查询时间而言是可以接受的。

感谢各位的阅读,以上就是“elasticsearch 的 ScanScroll 如何使用”的内容了,经过本文的学习后,相信大家对 elasticsearch 的 ScanScroll 如何使用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是丸趣 TV,丸趣 TV 小编将为大家推送更多相关知识点的文章,欢迎关注!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-16发表,共计2561字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)