데이터베이스/Elasticsearch

Elasticsearch에서 Paging시 max_result_window 초과시 조회가 안되는 이슈

반응형

엘라스틱 서치에서 데이터를 paging 하여 조회할때 from과 size를 사용한다. 

from은 시작 지점을 이야기하고 size는 그 시작 지점으로 부터 몇 개의 데이터를 보여주어야 하는 건지 설정할 때 사용 되는 값이다. 그래서 계산 방법은 다음과 같다.

from : (page - 1) * size 

size : size


그럼  만약 3개씩 보여주는 페이지에서 2번째 페이지를 보여주기 위해서는 from은 3, size는 3으로 설정하면 된다.

1
2
3
4
5
6
7
8
9
GET wedul/_search
{
  "from": 3, 
  "size": 3, 
  "query": {
    "match_all": {}
  }
}
 
cs


그럼 만약 wedul 페이지를 접근하다가 다음과 같이 Document의 숫자가 10000을 넘어가게 되면 어떻게 될까? 쿼리를 사용해서 조회를 해보자.

1
2
3
4
5
6
7
8
9
GET wedul/_search
{
  "from": 9999, 
  "size": 3, 
  "query": {
    "match_all": {}
  }
}
 
cs


정상적인 결과가 나오지 않고 query_phase_execution_exception에러가 발생하고 다음과 같은 에러문구를 출력한다.

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


이유가 몰까? 이유를 잘 몰라서 엘라스틱 서치 공식홈페이지 문서를 뒤져봤다. 

엘라스틱서치에서 인덱스를 생성할 때 기본적으로 하나의 노드에 5 섯개의 shard가 생성되고 그 shard는 데이터를 나누어서 저장한다. 물론 그 데이터를 복제하고 있는 primary shard도 1로 설정되는데 이는 primary shard가 한개라는 뜻이 아니라 각 shard 마다 복제 shard가 한 개씩 존재한다는 의미이다, 

다시 본점으로 돌아가서 노드에 분리되어있는 파티션 shard들에 데이터가 분산되어 들어간다. 그래서 만약 5섯개의 shard가 있는 노드에 위치한 index에서 1 ~ 10 개의 데이터를 찾는다면 각 shard에서 10개의 데이터를 찾고 모아서 정렬작업을 한 후 50개의 데이터에서 1 ~ 10까지의 데이터를  반환한다.

그럼 10000개의 데이터라면? 각 shard에서 10000개의 데이터를 가져와서 모으고 그것을 정렬할 것이다. 그래서 총 50000개 이상의 데이터를 모아야 하고 그것을 정렬해야하기 때문에 성능적인 문제를 야기할 수 있다. 그래서 엘라스틱서치의 기본 검색 제한 document의 값은 10000이고 이 설정값 이름은 max_result_window이다.

이 값은 아래의 쿼리를 사용해서 원하는 대로 50000까지 설정할 수 있다. 하지만 근본적으로 10000을 넘게 조회하게되면 많은 리소스 사용으로 성능문제를 야기할 수 있기 때문에 함부로 설정값을 바꿀것이아니라 검색을 10000개가 한번에 되지 않도록 검색조건을 잘 분할해서 지정해야한다.

1
2
3
4
PUT your_index_name/_settings
  "max_result_window" : 500000 
}
cs


참조 

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

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

반응형