기록하는 습관

Elasticsearch (7) - Elasticsearch와 Lucene 본문

개발/Elasticsearch

Elasticsearch (7) - Elasticsearch와 Lucene

로그뉴 2022. 7. 6. 16:42

Elasticsearch Lucene

 

  1. Elasticsearch는 Shard 내부에 Lucene library를 가지고 있음
  2. Elasticsearch는 각 shard가 가지고 있는 Lucene을 제어할 수 있으며실시간 검색에 가깝게 동작하기 위해 주기적으로 인메모리 버퍼에 대해 Flush 작업을 수행함
  3. Lucene: 다수의 class로 구성된 검색 library이다.
    1. 중요한 class
      1. IndexWriter 데이터를 색인하는 클래스
      2. IndexSearcher : 색인된 데이터를 검색 결과로 제공하는 클래스
  4. Lucene 인덱스 내부에는 Segment 자료구조가 다수 존재.
    1. Segment를 이용해 검색을 수행함
    2. Segment는 역색인 구조.
  5. Lucene 인덱스의 한계
    1. 데이터를 저장할 때 물리 머신이 제공하는 리소스의 한계를 뛰어넘을 수 없음.
    2. 이를 ES shard가 뛰어넘음.

 


색인 작업 시 Segment의 기본 동작 방식

 

다수의 segment로 나누어져 있기 때문에 검색 요청을 분산 처리하여 효율적인 검색이 가능.

  • segment 단위 검색(Per-Segment Search)
    • Lucene은 검색 요청을 받으면 다수의 작은 segment 조각들이 각각 검색 결과 조각을 만들고 이를 합쳐 하나의 결과로 응답함.
  • Commit Point
    • Segment들 관리를 위해 Lucene이 제공하는 자료구조
    • 여러 segment 목록 정보를 가지고 있고검색 요청시 활용
    • IndexSearcher
      • 검색 요청 시 commit point를 이용해 가장 오래된 segment부터 차례로 검색 후 하나의 결과로 합쳐서 제공
    • IndexWriter
      • 최초 색인 작업 요청
        • IndexWriter에 의해 색인 작업을 진행 후 결과물로 하나의 segment 생성
      • 색인 작업 추가로 요청
        • 새로운 segment 추가로 생성되고 commit point에 기록됨
  • Segment 병합
    • Segment가 많아지면 읽기 성능이 저하됨 -> Lucene이 백그라운드에서 주기적으로 segment 파일 병합함.

 

 

  1. 최초 색인 요청
    1. IndexWriter segment를 생성
    2. IndexSearcher가 생성된 segment를 읽어 검색을 제공
  2. 추가 색인 요청
    1. IndexWriter segment를 추가 생성
    2. segment가 추가 생성되는 동안 기존 segment만 읽어 검색 결과를 제공
    3. segment 생성이 완료되면 생성된 모든 segment를 읽어 검색 결과를 제공
  3. 주기적으로 segment Merge 작업이 일어나는 경우
    1. IndexWriter Merge 대상이 되는 segment들을 복제 후 하나의 segment로 합침
    2. 복제본 segment들이 하나로 합쳐지는 동안 IndexSearcher는 원본 segment를 읽어 검색 결과를 제공
    3. 복제본 통합 작업이 완료되면 원본 segment와 교체하고 교체된 원본 segment들은 삭제
    4. IndexSearcher는 새로운 segment를 읽어 검색 결과를 제공합니다.

 

 


불변성(Immutability)

 

-        Lucene은 기본적으로 한 번 Disk에 저장된 segment는 수정이 불가능하도록 설계됨.

-        주기적인 Merge 작업에 의해 segment가 통합되고 삭제되기 전까지 수정 허용 x.

-        -> 색인 작업을 할 때마다 segment가 추가로 생성될 수 밖에 없는 구조!!!

 

장점

  1. 동시성 문제 회피
    1. 불변성이 보장되면 Lock이 필요 없기 때문.
  2. System cache 적극적으로 활용 가능
    1. 불변성을 보장하지 않을 경우 data가 변경될 때마다 system cache를 삭제하고 다시 생성해야 함
  3. 높은 cache 적중률 유지 가능
    1. System cache 수명이 길어짐 -> 검색 시 data를 항상 memory에 읽어올 수 있기에 성능 향상 가능!

 

  1. 수정 불가능이라 일부 데이터가 변경되더라도 전체 역색인 구조가 다시 만들어져야 함.
  2. 변경이 매우 빠르게 일어나면 실시간 반영 자체가 불가능
  3. 변경사항을 반영하려면 역색인을 다시 만들어야 하므로

 

-> 이런 단점 해결을 위해, 다수의 segment 생성해서 제공.

 

  1.  Segment에서 일부 data 삭제
    1. 삭제될 데이터가 포함된 segment의 삭제 여부 비트 배열 확인
    2. 삭제 여부 비트 배열의 flag를 삭제 표시
    3. IndexSearcher는 검색 작업 시 삭제 여부 비트 배열을 항상 먼저 확인 후 삭제 여부가 체크된 데이터를 검색 결과에서 제외
  2. Segment에서 일부 data 수정
    1. 위 과정에서 삭제 처리 먼저 수행
    2. 수정된 데이터를 새로운 segment로 생성
    3. IndexSearcher는 모든 segment를 읽어 검색 결과를 제공

 

* 삭제될 data가 물리적으로 삭제되는 시점

 

데이터 삭제 작업을 진행할 경우, 삭제 여부 비트 배열의 flag에 삭제 표시만 하고 실제로는 데이터 삭제하지 않음. 그렇다면, 실제 삭제되는 시점은?

 

문서 하나를 삭제하려면 전체 역색인 구조를 뒤져서 관련된 모든 텀을 제거해야 함. 이는 segment를 다시 생성하는 것과 다를게 없음. 

-> 백그라운드에서 주기적으로 일어나는 Merge 작업을 수행할 때 물리적으로 제거함.

Comments