Java 如何减少Elasticsearch滚动响应时间?
我有一个查询,从分布在我们集群中的7个不同索引返回了大约200K个点击。我将结果处理为:Java 如何减少Elasticsearch滚动响应时间?,java,
elasticsearch,Java,
elasticsearch,我有一个查询,从分布在我们集群中的7个不同索引返回了大约200K个点击。我将结果处理为: while (true) { scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(600000)).execute().actionGet(); for (SearchHit hit : scrollResp.getHits()){ //p
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.prepareSearch滚动行在返回下一组搜索点击之前可能会挂起一段时间。我运行代码的时间越长,情况似乎越糟
我的搜索设置为:
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));
.setSize(5000)
意味着每个客户端.prepareSearchScroll
调用将在每个碎片上检索5000条记录。您正在请求回源,如果您的记录很大,在内存中组装5000条记录可能需要一段时间。我建议试试小一些的。试试100和10,看看你是否有更好的表现
.setFrom(0)
不是必需的 你们可以在这里阅读这份文件
!
我认为Timevalue是保持滚动活动的时间
如果设置,将启用指定超时的搜索请求滚动
您可以在此处阅读更多内容:
我将在这里添加另一个答案,因为我对这种行为感到非常困惑,我花了很长时间才在@AaronM的评论中找到答案 这适用于使用JavaAPI的ES1.7.2 我滚动/扫描了一个包含5亿条记录的索引,但查询返回了大约40万行 我开始时的卷轴大小是1000,在我看来,从网络和CPU的角度来看,这是一个合理的权衡 这个查询运行得非常慢,大约需要30分钟才能完成,从光标抓取的间隔时间非常长 我担心这可能只是我正在运行的查询,不相信减小卷轴大小会有帮助,因为1000看起来很小 然而,看到上面AaronM的评论,我尝试了10的卷轴大小 整个工作在30秒内完成(这是我是否重新启动了ES,所以可能与缓存无关)——大约60倍的速度 因此,如果您在滚动/扫描时遇到性能问题,我强烈建议您尝试减小滚动大小。我在网上找不到太多关于这方面的信息,所以把它贴在这里。
- 查询数据节点不是客户端节点或 主节点
- 使用
属性选择所需的字段filter\u path
- 根据您的文档大小设置滚动大小,没有神奇的规则,您必须设置值并重试,等等
- 监控您的网络带宽
- 如果还不够的话,让我们来做一些多线程的事情:
要检索有关索引的碎片/节点详细信息,请使用API。是的,这肯定会使每个滚动响应更快。现在,许多小卷轴比一个大卷轴快吗?这取决于你的设置。对于非常小的批处理大小,您将获得网络通信开销;对于非常大的批处理大小,您将获得分配大块内存以收集整个批并将其保留在内存中的开销。甜点在中间的某个地方,但是你必须通过试验不同的批次大小来确定它。好的,我会试试看。我注意到的另一件事是滚动所需的时间不是恒定的。一段时间后,卷轴需要更长的时间。我怀疑我正在某处填满记忆。在我处理结果之后,我不需要这些结果,我是否应该在循环中进行某种内存刷新?您使用的是什么类型的查询?关于这个问题,很多批次比大批次快,我现在正在对此进行实验,并在我的应用程序中发现,我可以在30秒内以10的大小完成滚动。如果我将大小增加到100,总时间将变为300秒。非常奇怪,但分享我的经验给其他人看。你越减少滚动大小,执行的查询总数将增加。假设您的搜索结果总点击量为50K,并且您将滚动大小保持为10000,那么查询将执行5次,而滚动大小为10的查询执行次数少于5000次。查询执行时间通常是总体性能的主要部分。因此,不建议减小滚动大小。scroll API主要用于10000多个搜索结果,您可以在其中对结果进行分页。
setScroll(TimeValue keepAlive)