我有一个查询返回来自我们集群中分布的7个不同索引的〜200K命中。我将结果处理为:
while (true) {
scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(600000)).execute().actionGet();
for (SearchHit hit : scrollResp.getHits()){
//process hit}
//Break condition: No hits are returned
if (scrollResp.hits().hits().length == 0) {
break;
}
}
我注意到client.prepareSearchScroll行可以在返回下一组搜索命中之前挂起很长时间。我运行代码的时间越长,这似乎越来越糟。
我的搜索设置是:
SearchRequestBuilder searchBuilder = client.prepareSearch( index_names )
.setSearchType(SearchType.SCAN)
.setScroll(new TimeValue(60000)) //TimeValue?
.setQuery( qb )
.setFrom(0) //?
.setSize(5000); //number of jsons to get in each search, what should it be? I have no idea.
SearchResponse scrollResp = searchBuilder.execute().actionGet();
在检查许多结果时,预计扫描和滚动需要很长时间吗?我对弹性搜索很新,所以请记住,我可能会遗漏一些非常明显的东西。
我的查询:
QueryBuilder qb = QueryBuilders.boolQuery().must(QueryBuilders.termsQuery("tweet", interesting_words));
答案 0 :(得分:6)
.setSize(5000)
表示每个client.prepareSearchScroll
调用将检索每个分片5000条记录。您正在请求返回源,如果您的记录很大,则在内存中组装5000条记录可能需要一段时间。我建议尝试一个较小的数字。尝试100和10,看看你是否获得了更好的表现。
.setFrom(0)
没有必要。
答案 1 :(得分:2)
我将在这里添加另一个答案,因为我对这种行为感到非常困惑,我花了很长时间才在@AaronM的评论中找到答案
这适用于ES 1.7.2,使用java API。
我正在滚动/扫描500米记录的索引,但是查询返回大约400k行。
我开始时的卷轴大小为1,000,在网络和CPU方面,我觉得这是一个合理的权衡。
此查询运行速度非常慢,大约需要30分钟才能完成,光标提取之间会有很长时间的暂停。
我担心这可能只是我正在运行的查询,并且不相信减小滚动大小会有所帮助,因为1000看起来很小。
然而,看到AaronM的评论,我尝试了10的滚动大小。
整个工作在30秒内完成(这是我是否重新启动了ES,因此可能与缓存无关) - 加速大约60倍!!!
因此,如果您在滚动/扫描时遇到性能问题,我强烈建议您尝试减小滚动大小。我在互联网上找不到这个,所以在这里发布。
答案 2 :(得分:1)
filter_path
属性认为elasticsearch索引由多个分片组成。这种设计意味着您可以并行化操作。
让我们说你的索引有3个分片,你的群集3节点(通过索引获得比分片更多的节点)。
你可以在一个单独的线程中运行3个Java" workers",它们将搜索滚动不同的分片和节点,并使用队列来集中"结果。
这样,你的表现会很好!
这就是elasticsearch-hadoop库所做的。
要检索有关索引的分片/节点详细信息,请使用https://www.elastic.co/guide/en/elasticsearch/reference/current/search-shards.html API。
答案 3 :(得分:0)
我认为Timevalue是时候保持滚动活动了
setScroll(TimeValue keepAlive)
如果设置,将启用滚动指定超时的搜索请求。