fragile and resilient

Storage

[Elasticsearch] Near real-time search, Refresh

Green Lawn 2024. 2. 15. 22:30

색인 작업 시 세그먼트 동작 방식

엘라스틱서치는 내부적으로 Lucene이라는 라이브러리를 통해 검색 기능을 수행한다. 

검색 요청이 오면 Segment들이 각각의 검색 결과를 만들고 이를 통합해서 검색 결과를 응답하도록 되어있다.

루씬은 색인 작업 시 기존에 생성된 세그먼트에는 정보를 추가하거나 변경하지 않고, 색인 작업을 할 때마다 새로운 세그먼트 파일을 생성한다. 해당 방식으로 동작하는 이유는 Segment의 불변성을 유지해서 검색 성능을 보장하기 위함이다.

(새로운 세그먼트가 계속 생성되므로, 루씬은 백그라운드에서 세그먼트 파일을 병합하는 작업을 수행하고 이를 통해 모든 세그먼트들을 물리적으로 하나의 파일로 병합한다.)

이미지 출처: 엘라스틱서치 실무 가이드


Refresh

루씬은 효율적인 색인 작업을 위해 내부적으로 일정 크기의 In-memory buffer를 가지고 있다.

루씬에 색인 작업이 요청되면 전달된 데이터는 우선 인메모리 버퍼에 순서대로 쌓이고, 버퍼에 일정 크기 이상의 데이터가 쌓이거나 일정 시간이 흐를 경우 쌓인 데이터를 모아 세그먼트로 생성되고 디스크로 동기화한다.

하지만 디스크에 물리적으로 동기화하는 fsync는 매우 비용이 큰 연산이다. 따라서 루씬에서는 운영체제 내부 커널의 시스템 캐시에만 기록되고 리턴한 후, 실제 데이터는 특정한 주기에 따라서 디스크에 기록된다. 이러한 처리 과정을 루씬에서는 Flush, 엘라스틱서치에서는 Refesh 라고 부른다.

데이터의 변경사항을 버퍼에 모아뒀다가 일정 주기에 한 번씩 디스크에 동기화하는 작업까지 수행한다. (디스크로 동기화하는 작업은 루씬에서는 Commit, 엘라스틱서치에서는 Flush라고 한다.)

엘라스틱서치는 클러스터에 존재하는 모든 샤드에 대해서 기본으로 1s 이내에 한 번씩 Refresh 작업을 수행한다. →

실시간에 '가까운' 검색 Flush 작업이 Commit보다는 상대적으로 가벼운 작업이지만 비용이 꽤 발생하는 작업이므로 신중해야한다.

이미지 출처

위 내용을 이해하면 엘라스틱서치는 '거의' 실시간에 가까운 검색이 가능하다는 의미를 알 수 있다.


정리 및 유의할 점

  • ES 모든 샤드에서는 모든 업데이트를 즉각적으로 반영하는 것이 아니라 1초 이내로 Refresh가 되기 때문에, Refresh되기 이전에 조회하면 업데이트되지 않은 값을 응답할 수 있다.
  • 해당 문제를 해결을 위해 refresh 조건을 wait_for(refresh가 완료되기 전까지 기다린 후 응답하는 옵션)로 설정할 수 있다.
    • 하지만 wait_for를 설정하게 되면 당연하게도 응답이 느려진다. 성능 테스트해본 결과 같은 시간 대비 5배정도 처리량이 감소했음.
    • 처리 대기 중인 wait_for 요청이 index.max_refresh_listeners(기본값 1000)보다 많은 경우 강제로 즉시 refresh 될 수 있어 성능에 악영향을 줄 수 있다.
  • refresh=true(즉시 새로고침)는 인덱싱 및 검색 관점 모두에서 성능 저하가 없도록 신중하게 검증한 후에만 사용해야 한다고 권고하고 있다.
  • Elasticearch는 수정이 빈번한 경우에는 적합하지 않은 것 같고, 위에서처럼 즉시 업데이트되어 정합성이 항상 그 즉시 정확하게 맞아야 하는 경우에도 적합하지 않은 것 같다.

 

Referencse

권택환, 김동우 4, 엘라스틱서치 실무 가이드

https://www.elastic.co/guide/en/elasticsearch/reference/master/docs-refresh.html

https://www.elastic.co/kr/blog/nuxeo-search-and-lucene-oh-my

 

'Storage' 카테고리의 다른 글

[Elasticsearch] Shard Allocation 은 어떻게 결정될까?  (0) 2024.04.10
[Elasticsearch] No master is elected  (0) 2024.02.14
[MySQL] 인덱스 정리  (0) 2022.09.26