your programing

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

lovepro 2020. 10. 12. 08:00
반응형

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


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) 문제를 해결할 수있는 다른 옵션이 있습니까?


큰 페이지 매김이 필요한 경우 솔루션의 한 가지 변형은 max_result_window 값을 늘리는 것입니다.

curl -XPUT "http://localhost:9200/my_index/_settings" -d '{ "index" : { "max_result_window" : 500000 } }'

메모리 사용량이 증가함에 따라 ~ 100k 값을 찾을 수 없습니다.


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

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

여기에 이미지 설명 입력

PUT your_index_name/_settings
{ 
  "max_result_window" : 500000 
}

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

{
  "acknowledged": true
}

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

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, 메모리 및 대역폭을 사용하여 정렬 프로세스가 실제로 매우 무거워 질 수 있습니다. 따라서 딥 페이징을 사용하지 않는 것이 좋습니다.


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();
}

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


2) It does not seem that the scrolling API is an option for me but that I have to increase "index.max_result_window". Does anyone have any experience with this?

--> You can define this value in index templates , es template will be applicable for new indexes only ,so you either have to delete old indexes after creating template or wait for new data to be ingested in elasticsearch .

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

참고URL : https://stackoverflow.com/questions/35206409/elasticsearch-2-1-result-window-is-too-large-index-max-result-window

반응형