Elasticsearch refresh, flush

JunMyung Lee·2024년 4월 4일
0

Elasticsearch

목록 보기
34/41

Elasticsearch를 다루면서 대략적인 이론만 알고 있다보니, 어느순간 refreshflush를 같은 역할을 하는 기능으로 인지하고 있었다. 시나리오 예제를 통해 명확히 두 기능에 대한 차이를 설명하고자 한다.

다음과 같은 시나리오대로 테스트를 진행해보자.

PUT test_index

{
  "settings": {
    "refresh_interval": "-1"
  }, 
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "A": {
        "type": "text"
      }
    }
  }
}

POST test_index/_doc/1

{
  "A": "This is a value for field A."
}

GET test_index/_flush & _search

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

GET test_index/_refresh & _search

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "A" : "This is a value for field A."
        }
      }
    ]
  }
}

Refresh

  • 색인된 문서를 검색 가능하게 만드는 작업
  • 색인될 때 메모리 버퍼에 저장되고, refresh가 발생할 때 이 메모리 버퍼에 있는 문서들이 새로운 "검색 가능한" 세그먼트로 변환
  • 색인된 문서가 검색에 나타나기 위해서는 세그먼트(segment)가 파일 시스템에 커밋되어야 하며, 이 과정이 refresh에 해당
  • 이 세그먼트는 디스크에 기록되지만, 아직 트랜잭션 로그(translog)에 있는 데이터가 디스크에 완전히 커밋된 것은 아님
  • 기본적으로 Elasticsearch는 1초마다 refresh를 자동으로 수행(현재 테스트에서는 -1값으로 수행하지 않도록 설정)

Flush

  • 색인의 데이터를 디스크에 완전히 커밋하고, 트랜잭션 로그를 지우는 작업
  • 색인의 Lucene 세그먼트를 디스크에 영구적으로 기록하고, 트랜잭션 로그를 클리어하여 Elasticsearch가 재시작되거나 복구가 필요할 때 데이터를 복구할 수 있도록 처리
  • Flush는 시스템이나 Elasticsearch 자체에 의해 자동으로 수행될 수도 있고, 사용자가 수동으로 요청할 수도 있음

refresh는 새로 색인된 문서를 검색 가능한 상태로 만들기 위해 메모리에 있는 문서들을 새로운 검색 가능한 세그먼트로 변환한다. 이 과정을 통해 새로 색인된 문서들이 검색에 포함된다.

flush는 색인의 데이터를 디스크에 완전히 커밋하고, 트랜잭션 로그(translog)를 지우는 작업. Elasticsearch가 재시작되거나 복구가 필요할 때 데이터를 복구할 수 있도록 한다.

과정

  • 문서A가 색인될 때, 이 문서 메모리 버퍼에 저장
  • 메모리 버퍼에 있는 문서들이 검색 가능한 세그먼트로 변환이 되어야 하는데 refresh_interval: -1값으로 인하여 refresh가 발생하지 않아 검색 세그먼트 미생성
  • flush를 수행할 경우, 검색 세그먼트를 디스크에 저장해야하는데, refresh가 발생하지 않아서 검색이 가능한 상태가 아니기 때문에 디스크에 저장할 내용이 없고 검색 결과에 나타나지 않음

_id값으로는 조회시 검색이 가능

Elasticsearch의 문서 ID를 통한 조회와 일반 검색 쿼리를 처리하는 내부 매커니즘 차이

Elasticsearch는 내부적으로 문서를 색인할 때 바로 문서 ID에 대한 참조를 생성한다.
문서 ID를 사용하여 문서에 직접 접근하는 경우 (GET /index/_doc/document_id 형태의 요청), Elasticsearch는 색인의 내부 데이터 구조를 통해 해당 문서를 찾을 수 있다.

이는 문서가 아직 검색 가능한 세그먼트로 flush되지 않았거나 refresh되지 않았더라도 가능한데, 이러한 접근 방식을 실시간 GET이라고 불리며, 문서 ID를 알고 있는 경우에는 문서가 refresh되지 않았더라도 해당 문서를 검색할 수 있게 해준다.

과정

실시간 GET 기능은 Elasticsearch의 트랜잭션 로그(translog)를 사용하여 작동한다. 색인 작업이 수행될 때, 문서는 트랜잭션 로그에 기록되고, 이 로그는 문서 ID를 기반으로 문서를 검색할 수 있는 메커니즘을 제공합니다. 따라서, refresh가 발생하지 않았더라도 문서 ID를 통해 문서조회가 가능하다.

일반적인 검색 쿼리는 새로운 세그먼트가 생성되고 검색 가능한 상태가 되기 전까지 색인된 문서를 반환하지 못한다. 이는 refresh 작업을 통해 이루어 진다.

flush가 일어나면 트랜잭션 로그는 정리되는데 그럼 문서ID검색은 안되어야 하는거 아닌가?

flush작업이 일어나면, 색인된 데이터가 Lucene 세그먼트로 디스크에 저장되었음을 보장한다. 문서 ID를 통한 검색 요청시 이 세그먼트가 검색작업에 사용되게 된다.
즉, 문서 ID검색 요청은 트랜잭션 로그도 찾고, 세그먼트에서도 찾는다

profile
11년차 검색개발자 입니다. 여러 지식과 함께 실제 서비스를 운영 하면서 발생한 이슈에 대해서 정리하고 공유하고자 합니다.

0개의 댓글