일래스틱서치 블로그에서 일래스틱서치 5.0의 집계 기능 향상한 내용을 공유한다. 



출처 : https://www.elastic.co/blog/the-great-query-refactoring-thou-shalt-only-parse-once









https://github.com/elastic/elasticsearch/issues/10217





집계는 일래스틱서치 초기 버전부터 매우 비쌌고, 가장 많은 메모리를 소비했었다. 일래스틱서치 1.4에서는 샤드 쿼리 캐시(shard query cache)라고 하는 새로운 기능이 추가되었다. 샤드 쿼리 캐시 기능은 샤드 요청 캐시로 이름이 바뀌어 있었다. 샤드 쿼리 캐시의 장점은 한 인덱스 또는 하나 이상의 인덱스에 대해 검색 요청이 실행될 때, 관련된 각 샤드가 로컬에서 검색을 실행하고 해당 로컬 결과를 코디네이팅 노드(coordinating node)에 리턴한다. 해당 코디네이팅 노드는 각 샤드의 로컬 결과를 전체 결과 집합으로 합친다. 샤드 요청 캐시 모듈은 각 샤드의 로컬 결과를 캐시해서 검색 요청에 대한 결과를 즉시 리턴할 수 있도록 한다.


일래스틱서치 5.0버전 이전까지는 두 개의 명백한 문제로 인해 해당 기능이 기본적으로 비활성화였다. JSON의 순서는 결정적(deterministic)이지 않아서 두 요청이 논리적으로 동일할 수도 있지만 JSON 문자열에 렌더링 될 때는 동일하지 않을 수 있다. 전체 JSON 문자열을 기반으로 하는 샤드 캐시 키는 동일한 쿼리가 캐시의 이점을 얻을 수 없다.


대부분의 경우 사용자 쿼리는 시간 기반이고 특히 현재 시간과 관련되어 있으므로 후속 요청은 약간 다른 시간 범위를 갖는 경향이 있다. 따라서 해당 캐시를 활성화하면 캐시 히트가 거의 발생하지 않기 때문에 대부분의 경우 메모리가 낭비될 수 있다.


그러나 일래스틱서치 개발자는 지난 몇 년 동안 해당 이슈를 피하고자 샤드 레벨의 캐시 집계를 즉각적으로 만들어 기본 기능으로 제공하기 위해 많은 노력을 기울였다. 이는 검색 실행 코드의 주요 쿼리 리팩토링을 통해 가능해졌다.


5.0 이전 버전에서는 각 노드에서는 JSON 포맷의 원래 검색 요청을 수신하고 쿼리를 파싱하며 쿼리 구문의 일부로 실행되었던 루씬 쿼리를 실제로 생성하기 위해 샤드의 사용 가능한 정보(매핑과 같은 정보)를 사용했다.


5.0에서는 기존 오버 헤드가 완전히 제거되었다. 쿼리 파싱은 이제 요청을 수신하는 코디네이팅 노드에서만 발생하고 검색 요청을 사용할 수 있는 매핑과 상관 없이 직렬화 할 수 있는 중간 포맷(모든 노드가 이해할 수 있는 중간 쿼리 객체)으로 변경한다. 그런 다음 중재자 쿼리 객체는 모든 노드에서 구문 분석되어 샤드에 있는 매핑과 정보를 기반으로 실제 루씬 쿼리로 변환된다. 7장, '로우 레벨 인덱스 제어'에서 캐시에 대해 자세히 다룰 예정이다. 


샤드 요청 캐시는 일래스틱서치 5.0에서 기본적으로 "size": 0 인 모든 요청에 ​​대해 활성화된다. 샤드 요청 캐시는 사용자가 응답 시 다큐먼트를 리턴하지 않고 집계 결과를 사용해 데이터 전체적인 개요를 얻는 것에 관심있는 분석 사용 사례에 가장 유용하다.

Posted by '김용환'
,