검색 엔진(Search Engine)은 대규모 문서를 색인(Index)하고 사용자 쿼리에 관련성 높은 결과를 빠르게 반환하는 시스템이다. Elasticsearch의 내부 구조를 중심으로 설계 원리를 다룬다.
핵심 구성 요소
[크롤러] → [파서/분석기] → [역색인(Inverted Index)]
↓
[사용자 쿼리] → [쿼리 파서] → [검색 엔진] → [랭킹] → [결과]
역색인 (Inverted Index)
문서:
Doc1: "the quick brown fox"
Doc2: "the fox jumped over"
Doc3: "quick brown dog"
역색인:
"the" → [Doc1, Doc2]
"quick" → [Doc1, Doc3]
"fox" → [Doc1, Doc2]
"brown" → [Doc1, Doc3]
쿼리 "quick fox":
"quick" ∩ "fox" → Doc1 (두 단어 모두 포함)
포스팅 리스트 압축:
[1, 3, 7, 10] → Delta 인코딩: [1, 2, 4, 3]
Variable-Length Encoding으로 추가 압축
텍스트 분석 파이프라인
입력: "Running Quickly Over Fox-Jumps"
1. 토크나이저: [Running, Quickly, Over, Fox-Jumps]
2. 소문자화: [running, quickly, over, fox-jumps]
3. 불용어 제거: [running, quickly, fox-jumps]
4. 형태소 분석 (Stemming): [run, quick, fox, jump]
5. N-gram: [run quick, quick fox, fox jump]
색인된 토큰으로 역색인 생성
BM25 랭킹
TF-IDF 개선판: BM25 (Best Match 25)
score = Σ IDF(t) × (TF(t,d) × (k+1)) / (TF(t,d) + k×(1-b+b×|d|/avgdl))
매개변수:
k=1.5: TF 포화 (반복 출현 체감 반환)
b=0.75: 문서 길이 정규화
BM25 → 벡터 검색 (Dense Retrieval, ANN) 보완으로
의미론적 유사성 (시맨틱 서치) 처리
Elasticsearch 샤딩
인덱스 → N개 Primary Shard (병렬 처리)
→ M개 Replica Shard (가용성, 읽기 확장)
검색:
1. 코디네이터 노드: 모든 샤드에 쿼리 브로드캐스트
2. 각 샤드: 로컬 top-K 반환
3. 코디네이터: 병합·재랭킹 후 최종 top-K 반환
샤드 개수 결정:
샤드 당 10~50GB 권장
너무 많은 샤드 → 오버헤드
관련 문서