[Search] ElasticSearch 기본 원리: Inverted Index, Segment, Lucene
ES 기본 원리, inverted index, 역색인, Lucene segment, near real-time, refresh interval, translog, Lucene
정의
ES 의 모든 동작 은 Lucene 의 inverted index 위에 얹혀있다. 문서 단위 저장 + term 단위 검색 의 분리.
Inverted Index (역색인)
위 trie 의 prefix tree 구조 가 term dictionary 의 직관. Lucene 은 FST (Finite State Transducer) 라는 압축된 trie 사용.
일반 정방향 인덱스 vs 역색인
flowchart LR
subgraph Forward["Forward Index (DB)"]
D1["doc 1: 'rabbit hat'"]
D2["doc 2: 'red rabbit'"]
D3["doc 3: 'big hat'"]
end
subgraph Inverted["Inverted Index (Lucene)"]
T1["'rabbit' → [1, 2]"]
T2["'hat' → [1, 3]"]
T3["'red' → [2]"]
T4["'big' → [3]"]
end
| 정방향 | 역색인 |
|---|---|
| doc → terms | term → docs |
| RDB 의 row | 검색에 최적 |
LIKE '%rabbit%' = O(N) | term 으로 즉시 lookup |
검색 흐름
sequenceDiagram
autonumber
Client->>ES: GET /idx/_search { "match": { "title": "rabbit hat" } }
ES->>Analyzer: 쿼리 분석 (tokenize)
Analyzer-->>ES: tokens: ["rabbit", "hat"]
ES->>Inv: term lookup
Inv-->>ES: postings: rabbit=[1,2], hat=[1,3]
ES->>ES: intersection / union (BM25 score 계산)
ES->>ES: 정렬 (score desc)
ES-->>Client: top hits
Segment: Lucene 의 단위
flowchart TB
Shard[Shard]
Shard --> Seg1["Segment 1<br/>(불변)"]
Shard --> Seg2["Segment 2<br/>(불변)"]
Shard --> Seg3["Segment 3<br/>(불변)"]
Shard --> Seg4["Segment N<br/>(최신)"]
| 속성 | 의미 |
|---|---|
| Immutable | segment 는 생성 후 절대 변경 안 됨 |
| Append-only | 새 문서 = 새 segment |
| Merge | 여러 segment 를 주기적으로 큰 하나로 (background) |
| Delete | 삭제 = 별도 .del 파일에 표시 (실제 제거는 merge 시) |
IMPORTANT
Segment 의 불변성 이 ES 의 concurrent search + write 가능 의 토대. 동시 읽기에 lock 없음.
Near Real-Time: refresh
sequenceDiagram
autonumber
participant App
participant Buf as In-memory Buffer
participant FS as FS Cache (segment)
participant Disk
App->>Buf: index doc (즉시 검색 안 됨)
Note over Buf: refresh interval (1초 기본)
Buf->>FS: refresh → 새 segment (검색 가능!)
Note over FS: 메모리 cache 에 있을 뿐 디스크 아직
Note over FS: flush 주기
FS->>Disk: fsync (durable)
| 동작 | 주기 | 의미 |
|---|---|---|
| Buffer → Refresh | 1초 (refresh_interval) | 검색 가능 (still in memory) |
| Refresh → Flush | index.translog.flush_threshold_size | 디스크 fsync |
| Merge | 백그라운드 | 작은 segment 들 → 큰 segment |
TIP
대량 인덱싱 시 refresh_interval: -1 로 끄면 수배 빠름. 인덱싱 후 명시적 _refresh.
Translog (WAL)
flowchart LR
Write[Index API] --> Buf[Buffer]
Write --> TL["Translog<br/>(WAL)"]
TL -->|fsync 주기| Disk
Refresh 와 무관하게 write 가 안전. 자세한 건 wal-write-ahead-log.
| 모드 | 동작 |
|---|---|
request (기본) | 매 요청 fsync (느림, 안전) |
async | 주기적 fsync (5s 기본) |
Document 와 ID
PUT /products/_doc/sku-1234
{
"name": "Mechanical Keyboard",
"price": 129.99,
"tags": ["accessory", "input"]
}
| 필드 | 의미 |
|---|---|
_index | 인덱스 이름 |
_id | 문서 ID (없으면 자동 생성) |
_source | 원본 JSON (저장 + 반환용) |
_version | 낙관적 동시성 제어 |
_seq_no, _primary_term | versioning 의 개선판 |
Routing
shard = hash(routing) % number_of_primary_shards
- 기본
routing = _id. - 같은 routing → 같은 shard.
- 멀티 테넌트 에서
routing = tenant_id로 데이터 locality.
자세한 영역
- 인덱싱 흐름 + mapping: elasticsearch-indexing
- 쿼리 종류: elasticsearch-query
- cluster, shard: elasticsearch-infrastructure
- BM25: elasticsearch-relevance-scoring
- 한국어 분석: elasticsearch-korean-indexing
관련 위키
- elasticsearch (개요)
- btree-indexing (RDB 인덱스 비교)
- Redis Vector Search (대안)
- trie (FST 의 토대)
이 글의 용어 (10개)
- [DB Internals] B-Tree와 B+Tree 인덱싱database-internals
- 정의 B-Tree (B+ Tree) 는 거의 모든 RDB 의 인덱스 자료구조. balanced tree, 디스크 I/O 최소화 설계. 특징: - 균형 (balanced): 모든 …
- [DB] WAL: Write-Ahead Log, crash recovery, replication 의 토대database-internals
- 정의 Write-Ahead Log (WAL) = 데이터 변경 전 로그를 먼저 디스크에 기록. 모든 모던 RDB / KV / 분산 시스템의 내구성 기반. 핵심 약속: 로그가 디스크…
- [Redis] Vector Search: HNSW, SVS-VAMANA, Semantic Cachedatabase-internals
- 정의 Vector Search 는 임베딩 벡터의 거리/유사도 기준으로 근접한 K 개 를 찾는 검색. Redis 는 RediSearch 모듈 (Redis 8 부터는 코어) 과 Va…
- [Search] ElasticSearch: Lucene 위 분산 검색 엔진search
- 정의 ElasticSearch = Apache Lucene 위의 분산 RESTful 검색/분석 엔진. 2010 출시. Logstash + Kibana + Beats 와 함께 El…
- [Search] ES 인프라: cluster, shard, replica, ELKsearch
- 정의 ES 는 분산 시스템. cluster + multiple nodes + shards + replicas + Elastic Stack 보조 도구. Cluster 구조 Node…
- [Search] ES 한글 인덱싱: nori, mecab, 형태소 분석search
- 정의 한국어 는 교착어 + 띄어쓰기 모호 + 형태소 변화 때문에 공백 단순 분리 로는 검색 불가. 형태소 분석 (morphological analysis) 필수. 한글이 어려운 …
- [Search] ES Indexing: bulk, refresh, ingest pipelinesearch
- 정의 Indexing = JSON 문서를 역색인에 등록 하는 행위. Lucene segment 빌드 + refresh + flush 의 흐름. 단일 인덱싱 | 동작 | 결과 | …
- [Search] ES Query: must / should / filter / must_notsearch
- 정의 ES 의 Query DSL = JSON 기반 표현력 풍부한 쿼리 언어. bool query + leaf query 의 조합. bool query: 4가지 절 | 절 | AN…
- [Search] ES Relevance Scoring: BM25, TF-IDF, function_scoresearch
- 정의 Relevance Score ( ) = 쿼리와 문서의 매칭 강도. ES 7+ 의 기본은 BM25 (TF-IDF 의 발전형). BM25 공식 | 부분 | 의미 | |---|-…
- 트라이 (Trie, 접두사 트리)algorithm
- 정의 트라이 (Trie) 는 Edward Fredkin 이 1960년 제안한 문자열 집합을 저장하는 트리 자료구조. 각 노드는 문자 하나, 간선은 다음 문자로의 전이. 루트에서 …
💬 댓글