繁体   English   中英

使用 Spring Data Elasticsearch 进行“扫描和滚动”查询期间的 Elasticsearch SearchContextMissingException

[英]Elasticsearch SearchContextMissingException during 'scan & scroll' query with Spring Data Elasticsearch

我正在使用具有默认集群配置的 elasticsearch 2.2.0。 我在使用 spring 数据弹性搜索时遇到扫描和滚动查询的问题。 当我执行查询时,我收到如下错误:

[2016-06-29 12:45:52,046][DEBUG][action.search.type       ] [Vector] [155597] Failed to execute query phase
RemoteTransportException[[Vector][10.132.47.95:9300][indices:data/read/search[phase/scan/scroll]]]; nested: SearchContextMissingException[No search context found for id [155597]];
Caused by: SearchContextMissingException[No search context found for id [155597]]
    at org.elasticsearch.search.SearchService.findContext(SearchService.java:611)
    at org.elasticsearch.search.SearchService.executeScan(SearchService.java:311)
    at org.elasticsearch.search.action.SearchServiceTransportAction$SearchScanScrollTransportHandler.messageReceived(SearchServiceTransportAction.java:433)
    at org.elasticsearch.search.action.SearchServiceTransportAction$SearchScanScrollTransportHandler.messageReceived(SearchServiceTransportAction.java:430)
    at org.elasticsearch.transport.TransportService$4.doRun(TransportService.java:350)
    at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

我的“扫描和滚动”代码:

public List<T> getAllElements(SearchQuery searchQuery) {
    searchQuery.setPageable(new PageRequest(0, PAGE_SIZE));
    String scrollId = elasticsearchTemplate.scan(searchQuery, 1000, false);
    List<T> allElements = new LinkedList<>();
    boolean hasRecords = true;
    while (hasRecords) {
        Page<T> page = elasticsearchTemplate.scroll(scrollId, 5000, resultMapper);
        if (page.hasContent()) {
            allElements.addAll(page.getContent());
        } else {
            hasRecords = false;
        }
    }
    elasticsearchTemplate.clearScroll(scrollId);
    return allElements;
}

当我的查询结果大小小于 PAGE_SIZE 参数时,会出现五次这样的错误。 我猜它是每个分片一个。 当结果大小大于 PAGE_SIZE 时,错误会多发生几次。 我试图重构我的代码以不调用:

Page<T> page = elasticsearchTemplate.scroll(scrollId, 5000, resultMapper);

当我确定页面没有内容时。 但它只有在 PAGE_SIZE 大于查询结果时才有效,所以它根本不是解决方案。

我必须补充一点,这只是在 elasticsearch 方面的问题。 在客户端,错误被隐藏,并且在每种情况下查询结果都是正确的。 有没有人知道是什么导致了这个问题?

谢谢你的帮助,

西蒙。

如果 ElasticSearch 系统关闭连接,我会收到此错误。 通常这正是@Val 所说的 - 死连接。 ES 中的事情有时会无缘无故地消失 - 主节点宕机,数据节点太拥挤,查询性能不佳,Kibana 在您进行查询的同时运行......我被所有这些同时击中时间或其他时间来获得此错误。

建议:增加初始连接时间 - 1000L 可能太短,无法获得所需的内容。 如果查询早点结束不会有什么坏处。

当我尝试快速提取太多数据时,这也会随机发生; 您可能有大量文档,并且尝试将 PAGESIZE 设为 50,000 可能有点太多了。 我们不知道您为 PAGESIZE 选择了什么。

建议:将 PAGESIZE 降低到 500 之类的值。或 20。看看这些较小的值是否会降低错误的速度。

我知道在迁移到 ES 2.3.3 后,这些问题减少了。

如果您的搜索上下文不再存在,通常会发生这种情况。

在您的情况下,您以 1 秒的超时时间开始扫描,然后每次扫描在 5 秒内处于活动状态。 应该是太低了。 保持搜索上下文活动的默认持续时间为 1 分钟,因此您可能应该将其增加到 60 秒,如下所示:

String scrollId = elasticsearchTemplate.scan(searchQuery, 60000, false);
...
Page<T> page = elasticsearchTemplate.scroll(scrollId, 60000, resultMapper);

我遇到了类似的问题,我怀疑 Spring Data Elasticsearch 有一些关于传递 Scroll-ID 的内部错误。 在我的情况下,我只是试图滚动整个索引,我可以排除@Val 他关于“如果您的搜索上下文不再存在时通常会发生这种情况”的回答,因为无论持续时间如何都会发生异常。 此外,异常在第一个 Page 之后开始,并在每个其他分页查询中发生。

就我而言,我可以简单地使用elasticsearchTemplate.stream() 它在内部使用 Scroll & Scan 并且似乎正确地传递了 Scroll-ID。 哦,使用起来更简单:

SearchQuery searchQuery = new NativeSearchQueryBuilder()
    .withQuery(QueryBuilders.matchAllQuery())
    .withPageable(new PageRequest(0, 10000))
    .build();

Iterator<Post> postIterator = elasticsearchTemplate.stream(searchQuery, Post.class);

while(postIterator.hasNext()) {
    Post post = postIterator.next();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM