실시간 검색

원본 보기

실시간 검색

문서가 Elasticsearch에 저장되면 색인되어 준실시간(near real-time)으로, 즉 1초 이내에 완전히 검색 가능한 상태가 됩니다. 준실시간 검색이란 무엇을 뜻할까요?

Elasticsearch의 기반이 되는 Java 라이브러리인 Lucene은 세그먼트 단위 검색이라는 개념을 도입했습니다. 세그먼트는 역색인과 유사하지만, Lucene에서 인덱스라는 단어는 "세그먼트의 모음과 커밋 지점"을 의미합니다. 커밋이 일어나면 새로운 세그먼트가 커밋 지점에 추가되고 버퍼는 비워집니다.

Elasticsearch와 디스크 사이에는 파일시스템 캐시가 있습니다. 인메모리 색인 버퍼에 있는 문서(그림 1)는 새로운 세그먼트로 기록됩니다(그림 2). 새 세그먼트는 먼저 파일시스템 캐시에 기록되고(비용이 적음), 이후에야 디스크로 플러시됩니다(비용이 큼). 다만 파일이 캐시에 올라온 뒤에는 다른 파일과 마찬가지로 열어서 읽을 수 있습니다.

인메모리 버퍼에 새 문서가 있는 Lucene 인덱스

Lucene은 전체 커밋을 수행하지 않고도 새 세그먼트를 기록하고 열 수 있게 해주며, 그 안에 담긴 문서를 검색에서 볼 수 있게 만듭니다. 이는 디스크로의 커밋보다 훨씬 가벼운 작업이므로 성능 저하 없이 자주 수행할 수 있습니다.

버퍼 내용이 세그먼트로 기록되어 검색은 가능하지만 아직 커밋되지 않은 상태

Elasticsearch에서는 새 세그먼트를 기록하고 여는 이 과정을 리프레시(refresh)라고 부릅니다. 리프레시는 마지막 리프레시 이후 인덱스에 수행된 모든 작업을 검색에서 사용할 수 있게 만듭니다. 리프레시는 다음과 같은 방법으로 제어할 수 있습니다.

  • 리프레시 간격을 기다리기
  • ?refresh 옵션 설정하기
  • Refresh API를 사용해 리프레시를 명시적으로 완료하기(POST _refresh)

기본적으로 Elasticsearch는 1초마다 인덱스를 주기적으로 리프레시하지만, 최근 30초 이내에 검색 요청을 한 번 이상 받은 인덱스만 대상으로 합니다. Elasticsearch가 실시간 검색을 제공한다고 말하는 이유가 여기에 있습니다. 문서 변경 사항은 즉시 검색에 반영되지는 않지만 이 시간 범위 안에 반영됩니다.