Indexing 이란 문서(DOC)들의 내용 중에서 검색하고자 하는 대상들을 쉽고 빠르게 찾을 수 있는 자료구조로 배치하는 것.
전통적인 RDBMS 에서는 like 검색을 사용하기 때문에 데이터가 늘어날수록 검색해야 할 대상이 늘어나 시간도 오래 걸리고, row 안의 내용을 모두 읽어야 하기 때문에 기본적으로 속도가 느림.
Elasticsearch는 데이터를 저장할 때 역색인(inverted index) 구조를 만들어 저장하여 관리
Elasticsearch에서는 추출된 각 키워드를 텀(term) 이라고 부르며 이렇게 Inverted Index가 있으면 term을 포함하고 있는 Documents의id를 바로 얻어올 수 있다.
이러한 특성 떄문에 Elasticsearch에서는 저장이 아닌 색인(Indexing) 이라고 함.
- Elastic Search는 Lucene 라이브러리를 이용하여 Indexing Data를 Inverted Index Data로 변환
- 변환 완료된 Inverted Index Data는 Lucene 세그먼트 파일로 파일 시스템에 저장된다.
문제는 어떤 단어로 index를 생성할지가 포인트가 된다. (영어라면 단순히 띄어쓰기로 하면 되지만..한글은?)
역색인은 두개의 하위 구조로 구성된다.
- 용어 사전 - 문서에 포함된 모든 용어를 정렬된 목록으로 그룹화
- 게시물 목록 - 각 용어의 목록을 생성하고 해당 용어가 있는 문서를 표시
위의 이미지에서 역색인되는 3개의 문서가 있고 문서의 내용을 역색인에 삽입되는 용어(stopword)로 분석(토큰)한다
inverted index에는 해당 용어가 있는 위치(문서번호)가 저장된다. 이로인해 특정 단어가 있는 문서를 빠르게 찾을수가 있다. (문서가 아닌 해당 inverted index 테이블만 검색하면 된다.)
2. 엘라스틱 서치 데이터 구조
엘라스틱서치는 위와 같이 데이터 (document)를 엘라스틱 인덱스로 만든 뒤, 샤드로 분리하여 보관하고 있다.
샤드는 논리적/물리적으로 분할된 인덱스로 루씬인덱스가 포함된다.
루씬은 새로운 데이터 (document)를 엘라스틱서치 인덱스에 저장할 때 "세그먼트 (segment)"를 생성하며,
세그먼트를 조합해 저장한 데이터의 검색 한다.
3. index module
3-1. segment
- elasticsearch의 샤드는 Lucene 인덱스이고, Lucene 인덱스는 shard단위로 나뉘며, 각 샤드는 세그먼트(물리적 파일) 단위로 나뉜다.
- 세그먼트는 Elastic Search(이하 ES)가 Lucene 라이브러리를 사용하여 생성하는 인덱싱 데이터의 단위로 복수 개의 파일로 구성
- 각 세그먼트들은 완전히 독립되어진 문서들의 집합이며 Inverted Index 구조로 생성된 실제 인덱싱 데이터로 구성되어짐
- 한번 생성된 세그먼트 파일은 수정이 불가능 (Immutability)
- Naming Format : "_" + "36진수{0-9,a-z}" /Segment가 생성될 때 마다 아래와 같이 순차적으로 증가하며 Naming 적용
번외
루신 파일 명
https://lucene.apache.org/core/8_3_0/core/org/apache/lucene/codecs/lucene80/package-summary.html
Summary of File Extensions
The following table summarizes the names and extensions of the files in Lucene:
The following table summarizes the names and extensions of the files in Lucene:
Segments File | segments_N | Stores information about a commit point |
Lock File | write.lock | The Write lock prevents multiple IndexWriters from writing to the same file. |
Segment Info | .si | Stores metadata about a segment |
Compound File | .cfs, .cfe | An optional "virtual" file consisting of all the other index files for systems that frequently run out of file handles. |
Fields | .fnm | Stores information about the fields |
Field Index | .fdx | Contains pointers to field data |
Field Data | .fdt | The stored fields for documents |
Term Dictionary | .tim | The term dictionary, stores term info |
Term Index | .tip | The index into the Term Dictionary |
Frequencies | .doc | Contains the list of docs which contain each term along with frequency |
Positions | .pos | Stores position information about where a term occurs in the index |
Payloads | .pay | Stores additional per-position metadata information such as character offsets and user payloads |
Norms | .nvd, .nvm | Encodes length and boost factors for docs and fields |
Per-Document Values | .dvd, .dvm | Encodes additional scoring factors or other per-document information. |
Term Vector Index | .tvx | Stores offset into the document data file |
Term Vector Data | .tvd | Contains term vector data. |
Live Documents | .liv | Info about what documents are live |
Point values | .dii, .dim | Holds indexed points, if any |
3-2. segment merge
es는 background로 merge scheduler를 통해 기존 세그먼트들을 새로운 세그먼트로 병합시도
merge를 통해 세그먼트 수를 줄이고 삭제된 문서들 삭제
데이터 추가
Elasticsearch에서 샤드 간에는 중복되는 데이터는 없다. 각 샤드는 독립적으로 데이터의 일부분을 저장하며, 서로 다른 Lucene 인덱스를 관리한다.
즉, 하나의 문서(document)는 오직 하나의 샤드에만 저장되며, 그 샤드 내의 Lucene 인덱스와 세그먼트에 기록된다.
샤드의 분산 처리
Elasticsearch는 데이터를 분산 저장하기 위해 인덱스를 여러 샤드로 나누고, 샤드마다 고유한 Lucene 인덱스가 있고, 이 Lucene 인덱스는 데이터를 세그먼트로 저장한다.
- 예를 들어, 하나의 Elasticsearch 인덱스에 5개의 샤드가 있다면, 각 샤드는 전체 데이터의 일부분을 가지고 있다.
- Elasticsearch는 데이터를 특정 샤드에 배정할 때 해시 함수를 사용하여 문서가 어떤 샤드에 저장될지 결정한다. 결과적으로 문서 A는 샤드 1에, 문서 B는 샤드 2에 저장되는 식으로 분산된다.
- 세그먼트 병합은 샤드 내에서만 이루어진다. 즉, 각 샤드의 Lucene 인덱스는 독립적으로 작동하며, 한 샤드의 세그먼트끼리만 병합된다. 서로 다른 샤드 간의 세그먼트는 병합되지 않는다.
검색
- 사용자가 검색 요청을 보내면, 해당 요청은 모든 샤드에 분배되어 각 샤드가 자신의 Lucene 인덱스를 검색
- 각 샤드의 Lucene 인덱스에서 검색된 결과는 중앙에서 모여 최종적으로 병합(merge) 및 리턴
검색시 샤드 선택은 성능에 중요한 영향을 미칠 수 있다. 같은 유형의 데이터가 한 샤드에 집중되는 것이 검색 성능을 향상시킬 가능성이 있다. 그 이유는, 관련성이 높은 문서들이 같은 샤드에 있을 경우, 검색 범위가 더 좁아지기 때문
Elasticsearch는 기본적으로 해시 기반 라우팅을 사용하여 문서를 특정 샤드에 할당 및 특정 필드에 기반해 데이터가 특정 샤드에 배치되도록 커스터마이징할 수 있다.
참고 자료
https://j.blaszyk.me/tech-blog/exploring-apache-lucene-index/
https://www.elastic.co/guide/en/elasticsearch/reference/8.15/
'Database > elastic search' 카테고리의 다른 글
1. Elasticsearch (0) | 2024.10.18 |
---|---|
Apache Lucene 4 (4) | 2024.10.17 |