Elasticsearch 2.1 : 결과 창이 너무 큽니다 (index.max_result_window)


88

Elasticsearch 2.1에서 정보를 검색하고 사용자가 결과를 통해 페이지를 볼 수 있도록합니다. 사용자가 높은 페이지 번호를 요청하면 다음 오류 메시지가 표시됩니다.

결과 창이 너무 큽니다. from + size는 [10000]보다 작거나 같아야하지만 [10020]이었습니다. 대규모 데이터 세트를 요청하는보다 효율적인 방법은 스크롤 API를 참조하십시오. 이 제한은 [index.max_result_window] 인덱스 수준 매개 변수를 변경하여 설정할 수 있습니다.

탄력적 문서는 이것이 높은 메모리 소비와 스크롤링 API를 사용하기 때문이라고 말합니다.

보다 큰 값은 검색 및 검색을 실행하는 샤드 당 상당한 힙 메모리 청크를 소비 할 수 있습니다. 이 값은 딥 스크롤 https://www.elastic.co/guide/en/elasticsearch/reference/2.x/breaking_21_search_changes.html#_from_size_limits에 대해 스크롤 API를 사용하기 때문에 그대로 두는 것이 가장 안전합니다.

문제는 큰 데이터 세트를 검색하고 싶지 않다는 것입니다. 결과 세트에서 매우 높은 데이터 세트에서만 슬라이스를 검색하고 싶습니다. 또한 스크롤 문서는 다음과 같이 말합니다.

스크롤은 실시간 사용자 요청을위한 것이 아닙니다. https://www.elastic.co/guide/en/elasticsearch/reference/2.2/search-request-scroll.html

이로 인해 몇 가지 질문이 남습니다.

1) 결과 10000-10020에 대한 "일반"검색 요청을 수행하는 대신 스크롤링 API를 사용하여 결과 10020까지 스크롤 (및 10000 미만의 모든 항목 무시)하면 메모리 소비가 실제로 더 낮을까요 (그렇다면 왜 그렇습니까)?

2) 스크롤 API가 옵션이 아닌 것 같지만 "index.max_result_window"를 늘려야합니다. 누구든지 이것에 대한 경험이 있습니까?

3) 문제를 해결할 수있는 다른 옵션이 있습니까?

답변:


80

깊은 페이지 매김이 필요한 경우 가능한 한 가지 해결책은 값을 늘리는 것입니다 max_result_window. curl셸 명령 줄에서이 작업을 수행 하는 데 사용할 수 있습니다 .

curl -XPUT "http://localhost:9200/my_index/_settings" -H 'Content-Type: application/json' -d '{ "index" : { "max_result_window" : 500000 } }'

~ 100k의 값에 대해 증가 된 메모리 사용량을 알아 차리지 못했습니다.


나는 같은 오류 'Result window is too large, from + size must be less than or equal to: [10000] but was [47190]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level parameter.')가 있습니다 4719 페이지 (모든 페이지 10 결과)가 있다고 말했습니다. 그리고 당신의 제안이 효과가 있다고 생각합니다.
dotslash

1
500000 미만의 소량 문서에 적합한 솔루션입니다.
Ezzat

2
저는 ES v2.2.0을 사용하고 { "max_result_window" : 500000 }있으며 이것이 작동 하려면 페이로드를로 변경 해야했습니다. 컬 명령이되었다 그래서 -curl -XPUT "http://localhost:9200/my_index/_settings" -d '{ "max_result_window" : 500000 }'
Parin Porecha

3
새로운 버전의 elasticsearch에 대해이 명령으로 헤더 오류가 발생하는 경우 헤더도 전달해야합니다. curl -XPUT " localhost : 9200 / my_index / _settings "-H "Content-Type : application / json"-d '{ "index": { "max_result_window": 50000}} '
Satys

32

올바른 해결책은 스크롤링을 사용하는 것입니다.
그러나 결과 search반환을 10,000 개 이상 으로 확장하려는 경우 Kibana를 사용하여 쉽게 수행 할 수 있습니다.

Dev Tools새로운 최대 결과 창을 지정하여 색인 (your_index_name)으로 이동 하여 다음을 게시하십시오.

여기에 이미지 설명 입력

PUT your_index_name/_settings
{ 
  "max_result_window" : 500000 
}

모든 것이 잘되면 다음과 같은 성공 응답이 표시되어야합니다.

{
  "acknowledged": true
}

1
Elasticsearch 코드 (put_settings 등)에서이 작업을 수행하는 방법을 시도했지만 많은 오류가 발생했습니다. 이렇게하면 시간이 절약됩니다! 감사합니다!
cpres

25

탄력적 문서의 다음 페이지에서는 딥 페이징에 대해 설명합니다.

https://www.elastic.co/guide/en/elasticsearch/guide/current/pagination.html https://www.elastic.co/guide/en/elasticsearch/guide/current/_fetch_phase.html

문서 크기, 샤드 수 및 사용중인 하드웨어에 따라 10,000 ~ 50,000 개의 결과 (1,000 ~ 5,000 페이지) 깊이 페이징을 완벽하게 수행 할 수 있습니다. 그러나 값이 충분히 크면 엄청난 양의 CPU, 메모리 및 대역폭을 사용하여 정렬 프로세스가 실제로 매우 무거워 질 수 있습니다. 따라서 딥 페이징을 사용하지 않는 것이 좋습니다.


1
그래서 여기서 우리는 깊은 페이지 매김을 포기해야합니다. 기본적으로 단일 뷰어에 대해 4000 페이지를 페이징하는 의미는 없습니다. 예를 들어 Google 검색에서 결과를 확인하기 위해 8 또는 9 페이지로 거의 스크롤하지 않습니다. 일반적으로 Google이 제공하는 상위 3 ~ 5 개 페이지 만 처리합니다.
dotslash

2
깊은 페이지 매김이 필요한 경우 스크롤 API를 사용할 수 있습니까?
Abhi.G

3
그러나 정렬 기능을 활성화 할 때 전자 상거래 사이트에서 예를 들어 보겠습니다. 사용자가 가장 높은 가격의 항목을보고 싶을 때. 가장 낮은 페이지로 정렬하고 마지막 페이지로 갈 때와 비교할 때 가장 높은 가격으로 정렬하면 결과가 달라집니다. 액세스 할 수있는 결과의 수를 제한하기 때문입니다. 이것에 대한 해결 방법이 있습니까?
MR Murazza

3

Scroll API를 사용하여 10000 개 이상의 결과를 얻으십시오.

ElasticSearch NEST API의 스크롤 예제

나는 이것을 다음과 같이 사용했습니다.

private static Customer[] GetCustomers(IElasticClient elasticClient)
{
    var customers = new List<Customer>();
    var searchResult = elasticClient.Search<Customer>(s => s.Index(IndexAlias.ForCustomers())
                          .Size(10000).SearchType(SearchType.Scan).Scroll("1m"));

    do
    {
        var result = searchResult;
        searchResult = elasticClient.Scroll<Customer>("1m", result.ScrollId);
        customers.AddRange(searchResult.Documents);
    } while (searchResult.IsValid && searchResult.Documents.Any());

    return customers.ToArray();
}

0

10000 개 이상의 결과를 원하는 경우 각 쿼리 요청에서 더 많은 결과를 반환해야하므로 모든 데이터 노드에서 메모리 사용량이 매우 높아집니다. 그러면 더 많은 데이터와 더 많은 샤드가있는 경우 해당 결과를 병합하는 것은 비효율적입니다. 또한 es는 필터 컨텍스트를 캐시하므로 다시 더 많은 메모리를 캐시합니다. 얼마나 정확하게 복용하고 있는지 시행 착오를 거쳐야합니다. 작은 창에서 많은 요청을받는 경우 10k 이상에 대해 여러 쿼리를 수행하고 코드에서 직접 병합해야합니다. 이는 창 크기를 늘리면 응용 프로그램 메모리를 덜 차지하게됩니다.


0

2) 스크롤 API가 옵션이 아닌 것 같지만 "index.max_result_window"를 늘려야합니다. 누구든지 이것에 대한 경험이 있습니까?

-> 색인 템플릿에서이 값을 정의 할 수 있습니다. es 템플릿은 새 색인에만 적용되므로 템플릿을 만든 후 이전 색인을 삭제하거나 새 데이터가 elasticsearch에서 수집 될 때까지 기다려야합니다.

{ "order": 1, "template": "index_template *", "settings": { "index.number_of_replicas": "0", "index.number_of_shards": "1", "index.max_result_window": 2147483647},


0

제 경우에는 from & size 접두사를 통해 쿼리에 대한 결과를 줄이면 모든 결과가 필요하지 않으므로 오류가 제거됩니다.

GET widgets_development/_search
{
  "from" : 0, 
  "size": 5,
  "query": {
    "bool": {}
  },
  "sort": {
    "col_one": "asc"
  }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.