Elasticseach 주요 용어
- Document : Elasticsearch가 저장하고 색인을 생성하는 JSON 형태의 데이터를 의미한다. 굳이 DB와 비교하면 Table의 각 row 개념이다.
- Index : 비슷한 Document를 모아놓은 단위이다. DB에서 Table과 대응된다.
- Shard : Index는 그 안의 document를 여러 shard로 분산 저장하여 고가용성을 보장한다. 원본 document는 primary shard에, 복제본은 replication shard에 저장된다.
- _id : Index 내 document에 부여하는 고윳값이다. 사용자가 직접 정해줄 수 있고, 정하지 않으면 Elasticsearch에서 중복되지 않도록 알아서 생성한다. 굳이 DB와 비교하면 primary key 개념이다.
- Node : Elasticsarch process의 실행을 Node라고 한다. (일반적으로 서버에 1개 Elasticsearch process를 띄우기 때문에 1개 서버로 봐도 된다.) Node는 안에 여러 개의 shard를 가진다. 고가용성 보장을 위해, 같은 Node 안에 동일 shard의 primary 버전과 replication 버전을 두지 않는다. (죽으면 같이 죽어서 가용성 보장이 안되기 때문에)
- Cluster : Elasticsearch의 서비스를 제공하는 하나의 묶음이다. 일반적으로 여러개의 Node를 묶어 1개의 Cluster를 구성한다. Node는 Cluster 내에서 각 기능을 가진다. (이것은 Cluster 형태의 데이터 구조의 공통점이기도 하다.)
Elasticseach과 Lucene
- Elasticsearch는 Lucene을 기반으로 개발된 엔진이다.
- Elasticsearch를 아주 간단히 정의하면 Lucene의 기능을 추상화하고 사용하기 편하도록 구성해 놓은 검색엔진이라고도 할 수 있을 정도로 Lucene은 Elasticsearch의 핵심 라이브러리이다.
- Elasticsearch에서 Lucence을 사용하는 방식은 다음과 같다.
[Lucene 동작]
1. Indexing
- 사용자가 Document를 JSON 형식으로 Elasticsearch에 요청하면, Elasticsearch는 이를 Analyze 하여 Token을 생성한다.
- 이 과정에서 Elasticsearch는 Lucene의 Analyzer를 사용하여 텍스트를 분할하고, 이를 기반으로 Inverted Index를 생성한다.
2. Flush
- Elasticsearch는 Lucence에서 만들어낸 Inverted Index를 바로바로 디스크에 저장하는 것이 아닌, memory 상에 저장하고 있다가 주기적으로 디스크에 Flush 하는 방식을 사용하여 Indexing 속도를 향상한다.
- Flush는 RAM 버퍼 크기가 설정된 한도를 초과하였을 때나 특정 조건(document 수 초과)이 충족되었을 때, 명시적으로 호출(indexWriter.flush())했을 때 수행된다.
- Flush까지 수행된 데이터에 대해 검색이 가능하다.
- 여기서 용어를 주의해야 할 것은 Lucene의 Flush는 Elasticsearch에서 Refresh에 해당한다. (정확히 말하면 Elasticsearch Refresh 과정에서 Lucene의 Flush를 호출하는 것이다. Elasticsearch에서 Flush는 Lucene의 commit 과정을 포함한다.)
3. Commit
- Flush가 디스크 상에 데이터를 기록하지만, 데이터 저장을 완전하게 보장하지 않는다. 이는 Flush가 디스크에 데이터를 임시로 기록했기 때문이다.
- Lucene은 주기적으로 fsync 시스템 콜을 통해, 페이지 캐시 내용과 디스크에 기록된 내용의 sync를 맞추는 작업을 수행한다.
- Commit까지 완료되면, 시스템 종료가 일어나도 데이터가 완전하게 저장되었음을 보장한다.
- Lucene에서 Flush는 되었고, Commit 되지 않은 경우 시스템이 비정상 종료되거나, 내부 인덱스 구조의 재구성이 일어나는 경우 translog에 의해 복구되는데, translog에 기록이 남지 않는 경우에는 데이터가 유실된다.
- 일반적으로 Commit은 개발자의 명시적 호출(IndexWriter.commit())로 일어난다.
* Traslog
- 변경사항을 바로 디스크에 반영하면 속도 이슈가 있기 때문에, 각 shard 내에서 변경사항을 기록하는 translog를 기록한다. 강제 종료 시, shard 복구 작업에서 translog에 적힌 내용을 기반으로 데이터를 복구한다.
4. Segment
- Segment는 Lucenec이 데이터를 저장하는 가장 작은 단위의 Index 파일 묶음이다.
- Commit까지 완료되어 디스크에 기록된 파일들은 Segment 단위로 검색된다.
- Segment는 불변의 데이터로 구성되어 있기 때문에, 새로운 document가 들어왔을 때는 새 segment가 생성되고, 기존 문서를 삭제하는 경우에는 실제 삭제를 하지 않고, Flag 표시만 해둔다. Update의 경우에는 삭제 Flag 처리를 해놓고, 새로운 Segment를 생성한다.
- Segment 개수는 불변이기 때문에, 계속 쌓이는 상황이 발생한다. Lucene에서는 무한정 늘어나는 현상을 방지하기 위해, 중간중간에 Segment 병합을 수행한다. 이때, GC처럼 삭제 플래그 데이터를 삭제한다.
5. Lucene Index
- 여러 segment들이 모여서 Lucene Index가 된다.
- Lucene은 이 Index 내에서만 검색이 가능하다.
- Elasticsearch의 Index 개념은 Lucene의 Index 개념과 다른데, Lucene의 Index는 Elasticsearch에 Shard에 대응되고, Index 내에서 검색하였을 때, 각 shard(즉, Lucene의 Index)에서 각각 검색하여 나온 결과를 병합하여 결과를 만드는 구조이다. 이로 인해 분산처리가 가능하다.
'ElasticSearch' 카테고리의 다른 글
ElasticSearch (1) 기본 개념 (25) | 2024.11.18 |
---|