빈쿵바라기
좌충우돌 개발자의 기록
빈쿵바라기
전체 방문자
오늘
어제
  • 분류 전체보기 (53)
    • Programming (25)
      • JAVA (12)
      • Spring Boot (6)
      • JPA (7)
      • Python (0)
    • Database (12)
      • RDBMS (4)
      • NoSQL (7)
    • Server (11)
    • Elasticsearch (3)
    • ETC (2)

블로그 메뉴

    공지사항

    인기 글

    최근 댓글

    최근 글

    티스토리

    hELLO · Designed By 정상우.
    빈쿵바라기

    좌충우돌 개발자의 기록

    [Elasticsearch] 전체 문서 조회 max_result_window 이슈 (Scroll API)
    Elasticsearch

    [Elasticsearch] 전체 문서 조회 max_result_window 이슈 (Scroll API)

    2022. 10. 20. 17:22

    Problem

    Elasticsearch에 색인되어 있는 문서(document)를 전체 조회해야 하는데, Elasticsearch에서는 데이터를 paging 하여 조회할 때 from과 size를 사용합니다. 그런데 Document의 숫자가 10,000번 째를 넘어가는 순간 데이터를 가져오지 못하고 아래와 같은 에러가 발생합니다.

    Result window is too large, from + size must be less than or equal to: [10000] but was [10010].
    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 setting.

    Elasticsearch의 설정 중 max_result_window 값이 10,000으로 설정되어 있습니다. 기본 검색 제한 document 건수를 하는 설정으로 그 이상의 문서를 조회할 때 성능문제를 야기할 수 있기 때문에 제한되어 있습니다.

     

    해결방법 1. max_result_window 설정 값 변경

    PUT /my_index/_settings
    { 
    	"index" : { 
        	"max_result_window" : 500000 
        } 
    }

    Index에 대해서 max_result_window 값을 원하는 만큼 늘려주면 됩니다.

    하지만, 너무 늘릴 경우 성능에 문제가 생길 수 있습니다. 실제로 5,000만 건 데이터를 조회할 때 두 배 이상 오래 결렸습니다.

     

    해결방법 2. Scroll API

    Scroll API는 전통적인 데이터베이스의 커서를 사용하는 것과 같이 하나의 search 요청에서 많은 수의 결과 리턴을 가능하게 해줍니다. Scrolling은 실시간으로 유저의 요청을 처리하기 위해 의도된 것이 아니라 대량의 데이터를 처리하기 위한 API입니다.

     

    Scroll API | Elasticsearch Guide [8.4] | Elastic

    You can also specify this value using the scroll request body parameter. If both parameters are specified, only the query parameter is used.

    www.elastic.co

     

    Example

    POST /my_index/_search?scroll=1m
    {
        "size": 100,
        "query": {
            "match" : {
                "title" : "elasticsearch"
            }
        }
    }

    먼저 위의 요청을 보내면 응답 값으로 _scroll_id 값을 포함한 검색 결과를 리턴합니다. 위의 예제에서 size를 100으로 요청하였으므로, 아래 예제처럼 scorll_id를 전달하면 아직 받지 못한 데이터를 100건씩 이어서 받을 수 있습니다.

    Query Parameter로 scroll=1m은 Scroll의 유지시간을 설정합니다. 생성된 Scroll를 사용하지 않으면, 설정한 시간이 지난 후 자동으로 메모리에서 소멸합니다.

    POST /_search/scroll 
    {
        "scroll" : "1m", 
        "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==" 
    }

    초기 요청 이후 다음 배치의 결과를 받기 위해서는 위와 같이 요청을 보내면 됩니다. scroll_id는 초기 검색 요청에서 응답 값으로 받아온 _scroll_id를 넘겨주면 됩니다. 

    • 초기 검색 요청과 그 이후의 각 스크롤 요청은 각각 _scroll_id를 반환합니다. _scroll_id는 요청 간에 변경될 수 있지만, 항상 변경되는 것은 아닙니다. 하지만 가장 최근에 받은 _scroll_id를 사용하여 다음 요청을 보내야 합니다.
    • 요청 URL에는 index명이 포함되어 있지 않습니다. scroll_id에 이미 index에 대한 정보를 포함하고 있습니다.
    • 응답 데이터에 hits.hits 의 size가 0이면 모든 결과값을 스크롤링한 것입니다.
    • 스크롤 요청에는 정렬 순서가 _doc일 때 더 빨리 최적화하여 응답합니다.
    POST /my_index/_search?scroll=1m
    {
      "sort": [
        "_doc"
      ]
    }

     

    저작자표시

    'Elasticsearch' 카테고리의 다른 글

    [Elasticsearch] 클러스터 구성하기  (0) 2023.03.09
    [Elasticsearch] maximum shards open 에러  (0) 2022.12.14
      'Elasticsearch' 카테고리의 다른 글
      • [Elasticsearch] 클러스터 구성하기
      • [Elasticsearch] maximum shards open 에러
      빈쿵바라기
      빈쿵바라기
      삽질하는 개발자의 좌충우돌 개발기

      티스토리툴바