elasticsearch,Java,elasticsearch" /> elasticsearch,Java,elasticsearch" />

Java 如何减少Elasticsearch滚动响应时间?

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

我有一个查询,从分布在我们集群中的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.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
    属性选择所需的字段
  • 根据您的文档大小设置滚动大小,没有神奇的规则,您必须设置值并重试,等等
  • 监控您的网络带宽
  • 如果还不够的话,让我们来做一些多线程的事情:
假设elasticsearch索引由多个碎片组成。这种设计意味着您可以并行化操作

假设您的索引有3个分片,集群有3个节点(按索引比分片多的节点是一种很好的做法)

您可以在一个单独的线程中运行3个Java“workers”,搜索滚动不同的碎片和节点,并使用队列“集中”结果

这样,你会有一个好的表现

这就是elasticsearch hadoop库所做的


要检索有关索引的碎片/节点详细信息,请使用API。

是的,这肯定会使每个滚动响应更快。现在,许多小卷轴比一个大卷轴快吗?这取决于你的设置。对于非常小的批处理大小,您将获得网络通信开销;对于非常大的批处理大小,您将获得分配大块内存以收集整个批并将其保留在内存中的开销。甜点在中间的某个地方,但是你必须通过试验不同的批次大小来确定它。好的,我会试试看。我注意到的另一件事是滚动所需的时间不是恒定的。一段时间后,卷轴需要更长的时间。我怀疑我正在某处填满记忆。在我处理结果之后,我不需要这些结果,我是否应该在循环中进行某种内存刷新?您使用的是什么类型的查询?关于这个问题,很多批次比大批次快,我现在正在对此进行实验,并在我的应用程序中发现,我可以在30秒内以10的大小完成滚动。如果我将大小增加到100,总时间将变为300秒。非常奇怪,但分享我的经验给其他人看。你越减少滚动大小,执行的查询总数将增加。假设您的搜索结果总点击量为50K,并且您将滚动大小保持为10000,那么查询将执行5次,而滚动大小为10的查询执行次数少于5000次。查询执行时间通常是总体性能的主要部分。因此,不建议减小滚动大小。scroll API主要用于10000多个搜索结果,您可以在其中对结果进行分页。
setScroll(TimeValue keepAlive)