본문 바로가기
BE 공부/검색엔진

[ElasticSearch] 내부 구조와 동작 원리

by 꼬질꼬질두부 2024. 7. 12.

역인덱스와 인덱스 용어

  • 역인덱스(Inverted Index): 용어를 문서와 그 위치에 매핑합니다. 이는 용어를 빠르게 찾고 그 용어가 포함된 문서를 식별하는 데 유용합니다. 예를 들어, "Winter is coming"이라는 문서가 있을 때, 'winter', 'is', 'coming' 각각의 단어를 문서와 연결하여 인덱스를 생성합니다.
    • 예시: "Winter is coming." -> {'winter': [1], 'is': [1, 2], 'coming': [1]}
  • 간단한 검색: 여러 용어로 검색할 때 각 용어의 발생 위치를 찾아 AND 검색의 경우 교집합을, OR 검색의 경우 합집합을 계산합니다.
    • 예시: 'Winter' AND 'coming' -> {'winter': [1], 'coming': [1]}의 교집합 = [1] (문서 1)
    • 예시: 'Winter' OR 'fury' -> {'winter': [1], 'fury': [2]}의 합집합 = [1, 2] (문서 1과 2)
  • 용어 변환: 효율적인 검색을 위해 용어를 적절히 변환하여 사용합니다. 예를 들어, 단어를 n-그램으로 분할하거나 지리 좌표를 지오 해시로 변환합니다.
    • 예시: 'yours' -> ['^yo', 'you', 'our', 'urs', 'rs$']

인덱스 구축

  • 우선순위: 검색 속도, 인덱스 압축, 인덱싱 속도, 변경 사항의 가시화 시간을 고려해야 합니다.
    • 검색 속도: 빠른 검색을 위해 인덱스를 최적화합니다.
    • 인덱스 압축: 델타 인코딩과 가변 바이트 수 사용 등으로 인덱스 크기를 최소화합니다.
    • 인덱싱 속도: 새로운 문서를 빠르게 추가할 수 있어야 합니다.
    • 가시화 시간: 변경 사항이 사용자에게 얼마나 빨리 반영되는지 중요합니다.
  • 압축 기법: 델타 인코딩과 가변 바이트 수 사용 등으로 인덱스 크기를 최소화합니다.
    • 예시: [42, 100, 666] -> [42, 58, 566] (델타 인코딩)
  • 불변 인덱스: Lucene의 인덱스 파일은 불변이며, 업데이트 대신 삭제 후 재삽입 방식으로 동작합니다.
    • 예시: 문서를 업데이트하려면 먼저 기존 문서를 삭제하고, 새로운 문서를 추가합니다.

인덱스 세그먼트

  • 세그먼트: Lucene 인덱스는 여러 불변 세그먼트로 구성되며, 각 세그먼트는 "미니 인덱스"입니다.
    • 예시: 새로운 문서가 추가될 때마다 메모리에서 인덱스를 생성하고, 일정 시간이 지나면 이를 디스크에 플러시합니다.
  • 세그먼트 병합: 세그먼트가 많아지면 Lucene은 이를 병합하여 삭제된 문서를 제거하고 인덱스 크기를 줄입니다.
    • 예시: 10개의 작은 세그먼트를 1개의 큰 세그먼트로 병합하여 인덱스 크기를 최적화합니다.
  • 캐시 무효화: 새로운 세그먼트가 생성될 때마다 일부 캐시가 무효화되어 검색 성능에 영향을 미칠 수 있습니다.
    • 예시: 새로운 세그먼트가 추가되면, 기존 캐시가 무효화되어 다시 로드해야 합니다.

Elasticsearch 인덱스

  • 인덱스와 샤드: Elasticsearch 인덱스는 여러 샤드로 구성되며, 각 샤드는 Lucene 인덱스입니다.
    • 예시: 문서가 추가될 때마다 샤드에 분산 저장됩니다. 샤드는 인덱스의 기본 확장 단위입니다.
  • 샤드 라우팅: 문서는 기본적으로 라운드 로빈 방식으로 샤드에 할당됩니다. 샤드 수는 인덱스 생성 시 지정되며 나중에 변경할 수 없습니다.
    • 예시: 문서 ID의 해시 값을 사용하여 문서를 특정 샤드에 할당합니다.
  • 트랜잭션 로그: Elasticsearch는 Lucene과 달리 트랜잭션을 지원하지 않지만, 트랜잭션 로그를 사용하여 문서를 영구 저장소에 기록합니다.
    • 예시: 문서를 인덱싱할 때 트랜잭션 로그에 추가하여 데이터 손실을 방지합니다.

댓글