[Search] ElasticSearch: Lucene 위 분산 검색 엔진
정의
ElasticSearch = Apache Lucene 위의 분산 RESTful 검색/분석 엔진. 2010 출시. Logstash + Kibana + Beats 와 함께 Elastic Stack (옛 ELK) 의 코어.
IMPORTANT
2026-06 시점 세계 가장 많이 쓰이는 검색 엔진. 전문 검색, 로그 분석, APM, SIEM, vector search, RAG 의 de facto.
라이센스 분기 타임라인
| 시점 | 이벤트 |
|---|---|
| 2010 | ES 출시. Apache 2.0 |
| 2021-01 | SSPL + ES License 로 전환 (AWS 와의 갈등) |
| 2021-04 | AWS 가 OpenSearch fork (ES 7.10 기반, Apache 2.0) |
| 2024-08 | Elastic 가 AGPLv3 추가 (blog). 8.16+ 부터 AGPL/SSPL/ES License 3-way 선택 |
| 2026 | ES 9.x stable 운영. OpenSearch 도 계속 활성 |
NOTE
Elastic 가 다시 OSI 호환 라이센스 (AGPL) 를 추가. OpenSearch 와의 경쟁 + 사용자 신뢰 회복 의 결합 결정. 단 managed cloud 운영 제약 은 SSPL 유지.
핵심 컴포넌트
flowchart LR
Beats[Beats / Elastic Agent] -->|input| LS[Logstash<br/>또는 Ingest pipeline]
LS --> ES[(Elasticsearch)]
ES --> Kib["Kibana<br/>(시각화 + 관리)"]
App[App] -->|REST + JSON| ES
App -->|ESQL| ES
| 컴포넌트 | 역할 |
|---|---|
| Elasticsearch | 분산 인덱스 + 검색 + 분석 |
| Kibana | UI, dashboard, dev tools, alerting |
| Logstash | 데이터 수집 + 변환 (옛). 현재 Ingest pipeline 이 대안 |
| Beats | 가벼운 shipper. Elastic Agent 로 통합 진행 중 |
| Fleet | Elastic Agent 의 중앙 관리 |
ES 의 본질
flowchart LR
Doc[JSON Document] -->|index API| Analyze["Analyzer<br/>(tokenize, normalize)"]
Analyze --> Inv["Inverted Index<br/>(term to docs)"]
Inv --> Lucene[(Lucene segments)]
Query[Query] -->|search API| Score[BM25 scoring]
Score --> Sort[Sort by relevance]
Sort --> Result[Top-K results]
- JSON 문서 단위 저장.
- 자동 inverted index 빌드.
- near real-time (인덱싱 후 1초 내 검색 가능).
- RESTful + JSON: HTTP 만 알면 사용.
자세한 원리는 elasticsearch-basics.
역인덱스 (Inverted Index) 원리
역인덱스 = term → 문서 ID 목록 매핑. Lucene 이 구현, ES 가 분산 래핑.
예시 문서:
| doc | 내용 |
|---|---|
| doc1 | ”quick brown fox” |
| doc2 | ”brown dog jumps” |
| doc3 | ”quick dog runs” |
인덱스 결과:
| Term | Posting list |
|---|---|
quick | doc1, doc3 |
brown | doc1, doc2 |
fox | doc1 |
dog | doc2, doc3 |
검색 quick AND dog → {doc1,doc3} ∩ {doc2,doc3} = doc3. O(1) 조회.
텍스트 필드 분석 파이프라인:
- Character filter: HTML 제거, 문자 변환
- Tokenizer: 공백/구두점 기준 분리
- Token filter: lowercase, stemming, stopword 제거
클러스터 / 노드 / 샤드 구조
flowchart LR
Client -->|"REST / ESQL"| Coord["Coordinating Node"]
Coord --> DN1["Data Node 1<br/>Primary P0, Replica R1"]
Coord --> DN2["Data Node 2<br/>Primary P1, Replica R0"]
Master["Master Node<br/>(클러스터 메타 관리)"] -.->|state| DN1
Master -.->|state| DN2
Ingest["Ingest Node<br/>(파이프라인)"] --> DN1
| 노드 역할 | 설명 |
|---|---|
| Master | 클러스터 상태, 인덱스 생성/삭제, 샤드 할당 관리 |
| Data | 실제 문서 저장 + 검색 처리 |
| Coordinating | 요청 파싱 + 샤드 분산 + 결과 집합 |
| Ingest | 인덱싱 전처리 파이프라인 (Logstash 대안) |
| ML | ML 모델 실행 (유료 기능) |
샤드 설계 원칙:
- 샤드 1개 권장 최대 크기: 20-50 GB (hot tier)
- 총 샤드 수 너무 많으면 클러스터 상태 비대화 → 오버샤딩이 최대 실수
- Replica 는 가용성 + 읽기 처리량 향상. 쓰기는 느려짐
index.number_of_shards는 생성 시 결정. 변경 불가 (rollover 필요)
PUT /my-index
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
}
}
샤드 라우팅 공식: shard = hash(document_id) % number_of_primary_shards
인덱싱 라이프사이클
flowchart LR
Doc[문서 색인 요청] --> Buffer["In-memory Buffer<br/>(index.buffer_size)"]
Buffer -->|"refresh (기본 1초)"| Segment["Lucene Segment<br/>(불변, 검색 가능)"]
Buffer -->|write| TLog["Translog<br/>(복구용 WAL)"]
Segment -->|"flush (30분 or 512 MB)"| FSS["디스크 (fsync)"]
TLog -->|flush 후 초기화| FSS
Segment --> Merge["Segment Merge<br/>(백그라운드)"]
Merge --> Segment
| 단계 | 동작 | 기본값 |
|---|---|---|
| Refresh | 버퍼 → 세그먼트. 검색 가능 | index.refresh_interval: 1s |
| Flush | translog + 세그먼트 → 디스크 commit | 30분 or 512 MB |
| Merge | 작은 세그먼트 병합. 삭제 문서 실제 제거 | 백그라운드 자동 |
IMPORTANT
bulk 인덱싱 시 refresh_interval: -1 설정 → 완료 후 수동 POST /index/_refresh. 5-10배 속도 향상.
JVM Heap 설정
# jvm.options
-Xms16g
-Xmx16g # 반드시 Xms = Xmx (동적 확장 방지)
| 규칙 | 이유 |
|---|---|
| 총 RAM 의 50% 이하 | 나머지 50% → OS page cache (Lucene file I/O) |
| 최대 30 GB | JVM Compressed OOPs 활성 유지 |
| Xms = Xmx | 런타임 확장 방지 (GC pause 최소화) |
| G1GC 기본 (7.0+) | 큰 heap 의 pause time 안정화 |
CAUTION
32 GB 이상 heap 설정 시 compressed OOPs 비활성 → 포인터 크기 2배 → 오히려 느려짐. 30 GB 이하 유지.
ES vs 다른 DB
| ElasticSearch | RDBMS | MongoDB | Solr | |
|---|---|---|---|---|
| 강점 | full-text search + analytics | 트랜잭션 | 문서 + flexible | full-text search |
| 약점 | 트랜잭션, write-heavy | full-text 약함 | 검색 약함 | 분산 운영 어려움 |
| Query | DSL + ESQL | SQL | MQL | DSL |
| Scaling | shard + replica | replica + read split | shard | shard |
| 사용 | search, log, APM | OLTP | 문서 + 모바일 | search (옛) |
ES 8.x → 9.x 주요 변화
| 영역 | 8.x | 9.x (2025+) |
|---|---|---|
| ESQL | 도입 (8.11) | 프로덕션 표준 |
| Vector | dense_vector + kNN | quantization 자동, BBQ |
| ELSER | 영문 모델 (sparse) | 다국어 + v2 |
| Inference API | 외부 LLM 통합 | endpoint 확장 |
| Bytes/Cost | 기본 | Search AI Lake (storage 분리) |
| Snapshots | 지원 | searchable snapshots 강화 |
활용 카테고리
flowchart TB
Use[ES 활용]
Use --> Search[Site search, e-commerce, autocomplete]
Use --> Log[Logs: Filebeat to ES to Kibana]
Use --> APM[APM, OpenTelemetry 통합]
Use --> SIEM["Security (SIEM), threat detection"]
Use --> Metrics[Metrics, Observability]
Use --> Vector[Vector search, RAG, semantic]
Use --> Geo[Geo search, maps]
운영 함정
WARNING
- 오버샤딩 = 샤드 수 / 노드 > 20 이상이면 클러스터 상태 비대 → master 부하. 작은 인덱스 = 적은 샤드.
- dynamic mapping 방치 = 예측 못한 필드 자동 매핑 → 매핑 폭발 + 타입 충돌.
dynamic: strict로 관리. - deep pagination (
from: 10000+) = 메모리 + 속도 문제. search_after 또는 scroll API 사용. - Index 를 Alias 없이 직접 노출 = 인덱스 재생성 (rolling) 불가. 처음부터 alias 로 추상화.
- snapshot 없는 운영 = 클러스터 다운 시 복구 방법 없음. Snapshot + ILM 필수.
- heap 32 GB 초과 = compressed OOPs 비활성 → 성능 역전. 30 GB 이하 유지.
관련 위키 (이 클러스터)
운영자 시점의 세부 페이지:
- elasticsearch-basics (Lucene, inverted index, segment)
- elasticsearch-query (must / should / filter / must_not)
- elasticsearch-indexing (인덱싱 흐름, refresh, flush)
- elasticsearch-mapping (field type, dynamic mapping)
- elasticsearch-korean-indexing (nori, mecab, 한국어 분석)
- elasticsearch-sort
- elasticsearch-aggregations (metric, bucket, pipeline)
- elasticsearch-relevance-scoring (BM25, function_score)
- elasticsearch-vector-search (kNN, ELSER, RAG)
- elasticsearch-infrastructure (cluster, shard, replica, Beats, ILM)
- elasticsearch-vs-opensearch (라이센스 분기)
인접 위키
- Redis Vector Search (대안 vector store)
- mongodb (문서 DB)
- Kafka (로그 수집 파이프)
- prometheus (메트릭 대안)
- opentelemetry (관측)
이 글의 용어 (16개)
- [DB] MongoDB: 문서 DB, WiredTiger, replica set, aggregationdatabase-internals
- 정의 MongoDB 는 BSON (binary JSON) 문서 기반 NoSQL DB. schema-less 라기보다 flexible schema. 2026 시점 Atlas (ma…
- [Distributed] Kafka: 분산 로그, partition, consumer groupdistributed-systems
- 정의 Apache Kafka = 분산 commit log. 고처리량 (수백만 msg/s), 영속, 수평 확장. event-driven 아키텍처 의 de facto. 핵심 개념: …
- [Observability] OpenTelemetry: 표준화된 trace/metric/logdevops
- 정의 OpenTelemetry (OTel) = observability 의 vendor-neutral 표준. CNCF. trace + metric + log 의 SDK + pro…
- [Observability] Prometheus: pull 기반 메트릭, PromQLdevops
- 정의 Prometheus = pull 기반 시계열 metric 시스템. PromQL 로 쿼리. CNCF graduated. 2026 클라우드 네이티브 메트릭 표준. 아키텍처 Pu…
- [Redis] Vector Search: HNSW, SVS-VAMANA, Semantic Cachedatabase-internals
- 정의 Vector Search 는 임베딩 벡터의 거리/유사도 기준으로 근접한 K 개 를 찾는 검색. Redis 는 RediSearch 모듈 (Redis 8 부터는 코어) 과 Va…
- [Search] ElasticSearch 기본 원리: Inverted Index, Segment, Lucenesearch
- 정의 ES 의 모든 동작 은 Lucene 의 inverted index 위에 얹혀있다. 문서 단위 저장 + term 단위 검색 의 분리. Inverted Index (역색인) 위…
- [Search] Elasticsearch vs OpenSearch: 라이센스 분기와 차이search
- 정의 OpenSearch = AWS 가 2021 년 Elasticsearch 7.10 에서 fork 한 Apache 2.0 라이센스 search engine. Kibana → O…
- [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 Aggregations: metric, bucket, pipelinesearch
- 정의 Aggregations (aggs) = ES 의 집계 분석. SQL 의 GROUP BY + 함수 + window. 검색 결과 또는 전체 위에서. 3가지 카테고리 Metric…
- [Search] ES Indexing: bulk, refresh, ingest pipelinesearch
- 정의 Indexing = JSON 문서를 역색인에 등록 하는 행위. Lucene segment 빌드 + refresh + flush 의 흐름. Lucene Segment 생명주기…
- [Search] ES Mapping: field type, dynamic, multi-fieldsearch
- 정의 Mapping = ES 의 schema. 각 필드의 type + analyzer + indexing 옵션. 대부분 immutable (재인덱싱 필요). Field Type …
- [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 공식 | 부분 | 의미 | |---|-…
- [Search] ES Sort: relevance, field, script, geosearch
- 정의 ES 의 기본 정렬 = relevance score (BM25) 내림차순. 명시적 sort 로 변경 가능. docvalues 로 메모리 효율적 정렬. 5가지 정렬 1. Fi…
- [Search] ES Vector Search: kNN, ELSER, RAGsearch
- 정의 ES 의 벡터 검색 = 임베딩 기반 의미 검색. kNN (Approximate Nearest Neighbor) 으로 수억 벡터 안에서 가까운 K개 찾기. 2026 시점의 E…
💬 댓글