2019. 8. 8. 15:33ㆍProgramming/python
elastic의 index table을 full scan 하려고 아래와 같이 코드를 작성해서 호출했다.
처음에 total size를 가져온 후 from의 window size를 옮겨가며 전체 데이터를 가져오는 방식이다.
그런데 위와 같이 작업 할 경우 아래와 같은 에러메시지가 나타나게 된다.
Limit of total fields 10000 in index has been exceeded.
해당 index에서의 최대 결과 윈도우는 기본으로 10000으로 설정되어 있으며( index.max_result_window) 해당 값을 넘어갈 시에 위와 같은 메시지가 발생한다.
내가 아무리 from을 13000, size를 100으로 줬다고 하더라도 es 내부에서는 전체 13100개를 가져온 후 0~13000개는 버리는 로직을 취하게 되고 결국에는 13100개를 가져오는 것과 동일한 작업을 하게 되는 것이다.
위의 코드로 실행하면 결국에는 10000개 이상의 결과는 가져올 수가 없게 된다. 또한 index.max_result_window 설정 값을 늘린다고 하더라도 성능 문제를 피할 수가 없다.
(만약 index.max_result_window를 50000을 주게 되면, 각각의 shard에서 50000개씩을 가져와서 sorting을 진행한 후 최종 50000개만을 가져오게 된다. 즉 각 shard에서 불필요한 50000개를 추가로 가져오게 되면 성능 문제를 야기시킬 수가 있다.)
해결 방법으로는 scroll이라는 기능을 통해 elastic search full scan을 진행 할 수가 있다.
_search 뒤에 scroll=1m이라고 주면 해당 scroll id를 1분 동안 유지하겠다는 의미가 된다.
그럼 우리는 이제 이 scroll id가 유지되는 동안 계속해서 data를 100개 단위로 가져올 수가 있다.
while 루프를 돌면서, 데이터가 존재하지 않을 때까지 해당 scroll id의 값을 계속적으로 호출하면 full scan 기능을 구현할 수가 있다.