2016-06-30 10 views
1

私はelasticsearch 2.2.0をデフォルトのクラスタ構成で使用しています。私は春のデータelasticsearchを使用してスキャンとスクロールのクエリに問題が発生します。Elasticsearch SearchContextMissingExceptionは、Spring Data Elasticsearchを使用した 'scan&scroll'クエリ中です。

[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パラメータ未満である場合には、このようなエラーが5を発生し、私は、クエリを実行すると私はこのようなエラーが出ます回。私はそれがシャードごとに1つだと思います。結果のサイズがPAGE_SIZEより大きい場合、エラーは数回発生します。

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

私はページにはコンテンツがありませんことを確信しているとき:私は呼んでいないために私のコードをリファクタリングしようとしました。しかし、PAGE_SIZEがクエリ結果よりも大きい場合にのみ機能するので、解決策はまったくありません。

私はそれがelasticsearch側にのみ問題であると付け加えなければなりません。クライアント側では、エラーは隠されており、いずれの場合もクエリの結果は正しいです。誰がこの問題の原因を知っていますか?

ありがとう、

サイモン。

答えて

0

これは、通常、検索コンテキストがもう生きていない場合に発生します。

あなたの場合、1秒のタイムアウトでスキャンを開始してから、5秒間、各スキャンが有効になります。それはおそらく低すぎます。あなたは、おそらくこのような60秒にそれを増やす必要がありますのでdefault duration、1分で生きている検索コンテキストを維持する:

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

私はそれを試してみましたが、私の場合はうまくいきません。私のサンプルクエリは非常にシンプルで、1秒未満しかかからず、問題になることはありません。 – esnosek

+0

もしあなたが確実にしたいなら、 'org.elasticsearch.search.SearchService'でDEBUGログを有効にすることができます。もし' freeing search context .... 'デバッグログが表示されたら、これが問題です。 – Val

+0

ありがとう、ありがとう、しかし、そのクラスのDEBUGログを有効にした後は何も変わっていません。エラーログは以前と同じです。 – esnosek

1

をElasticSearchシステムが接続を閉じた場合、私はこのエラーを取得します。通常、@Valが言ったことはまさにそれです。マスターノードがダウン、データノードが混雑している、悪い実行クエリ、Kibanaが同時にクエリを実行しているときに実行されています...私はこれらのすべてで1つ打たれましたこのエラーを取得するために時間または別のものを使用します。

提案:最初の接続時間を上げてください - 1000Lが必要なものを得るには短すぎます。クエリがより早く終了する場合、害はありません。

これは、あまりにも多くのデータをすばやくプルしようとするとランダムに発生します。あなたは巨大な文書を持っているかもしれませんし、50,000のPAGESIZEを引っ張ってみると、あまりにも多すぎるかもしれません。 PAGESIZEのためにあなたが選んだものはわかりません。

提案:500のようなものにPAGESIZEを下げます.20より小さい値がエラーを遅くするかどうかを確認します。

私は、ES 2.3.3に移行した後、これらの問題が少なくなっていることを知っています。

2

私は同様の問題に遭遇しました。私は、Spring Data ElasticsearchがScroll-IDを渡すことに関していくつかの内部的なバグを持っていると思われます。私の場合、インデックス全体をスクロールしようとしましたが、期間に関係なく例外が発生したため、@Valの答えは「これは通常、あなたの検索コンテキストがもう生存していない場合に発生します。また、例外は最初のページの後に開始され、他のすべてのページングクエリで発生しました。

私の場合は、単に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(); 
} 
関連する問題