2016-06-30 3 views
1

elasticsearch 2.2.0을 기본 클러스터 구성으로 사용하고 있습니다. 스프링 데이터 elasticsearch를 사용하여 스캔 및 스크롤 쿼리에 문제가 발생했습니다. 내가 쿼리를 실행하면이 같은 오류가 발생합니다 :Elasticsearch Spring 데이터 Elasticsearch를 사용하는 'scan & scroll'쿼리 중 SearchContextMissingException

[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 측에서만 문제가 있다는 것을 추가해야합니다. 클라이언트 쪽에서는 오류가 숨겨지고 각 경우에 쿼리 결과가 정확합니다. 아무도이 문제의 원인을 알고 있습니까?

감사합니다.

사이먼.

답변

0

일반적으로 검색 컨텍스트가 더 이상 작동하지 않는 경우에 발생합니다.

귀하의 경우 1 초의 시간 초과로 스캔을 시작한 다음 5 초 동안 각 스캔이 살아 있습니다. 아마 너무 낮을거야. 살아 검색 컨텍스트를 유지하는 default duration은 1 분입니다, 그래서 당신은 아마 이런 식으로 60 초를 증가해야 다음 ElasticSearch 시스템이 연결을 종료하는 경우

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

나는이 오류가 발생합니다. 일반적으로 그것은 @Val이 말한 것과 정확히 일치합니다. 마스터 노드가 다운되고, 데이터 노드가 너무 혼잡하며, 성능이 좋지 않은 쿼리와 쿼리를 실행하는 동시에 Kibana가 실행되는 경우가 있습니다.이 모든 것이 하나씩 충돌했습니다. 시간 또는 다른이 오류가 발생합니다.

제안 : 초기 연결 시간을 늘리십시오. 1000L은 필요한 시간을 얻기에는 너무 짧을 수 있습니다. 쿼리가 더 빨리 끝나면 상처를 입지 않습니다.

너무 많은 데이터를 빠르게 가져 오려고하면이 작업이 임의로 발생합니다. 당신은 거대한 문서를 가지고 있을지도 모른다. 그리고 50,000의 PAGESIZE를 잡으려고 노력하는 것은 조금 많이일지도 모른다. 우리는 당신이 PAGESIZE를 위해 무엇을 선택했는지 모른다.

제안 사항 : 500과 비슷한 값으로 낮추십시오. 20보다 작은 값으로 오류가 느려지는지 확인하십시오.

ES 2.3.3으로 이동 한 후 이러한 문제가 적다는 것을 알고 있습니다.

2

비슷한 문제가 발생하여 Spring Data Elasticsearch에 Scroll-ID 전달에 대한 내부 버그가 있다고 의심됩니다. 제 경우에는 전체 색인을 스크롤하려했는데, 기간에 관계없이 예외가 발생했기 때문에 @Val에 대한 답변은 "검색 컨텍스트가 더 이상 살아 있지 않다면 발생합니다"에 대한 답변을 제외 할 수 있습니다. 또한 예외는 첫 번째 페이지 이후에 시작되고 다른 모든 페이징 쿼리에 대해 발생합니다.

제 경우에는 간단히 elasticsearchTemplate.stream()을 사용할 수 있습니다.내부적으로 Scroll & Scroll을 사용하고 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(); 
} 
관련 문제