본문으로 건너뛰기
김신건의 로그

[Search] ElasticSearch: Lucene 위 분산 검색 엔진

· 수정 · 📖 약 4분 · 1,250자/단어 #elasticsearch #search #lucene #inverted-index #elk
ElasticSearch, Elastic, Elastic Stack, ELK, ES license, ES 8.x, ES 9.x

정의

ElasticSearch = Apache Lucene 위의 분산 RESTful 검색/분석 엔진. 2010 출시. Logstash + Kibana + Beats 와 함께 Elastic Stack (옛 ELK) 의 코어.

IMPORTANT

2026-06 시점 세계 가장 많이 쓰이는 검색 엔진. 전문 검색, 로그 분석, APM, SIEM, vector search, RAGde facto.

라이센스 분기 타임라인

시점이벤트
2010ES 출시. Apache 2.0
2021-01SSPL + ES License 로 전환 (AWS 와의 갈등)
2021-04AWS 가 OpenSearch fork (ES 7.10 기반, Apache 2.0)
2024-08Elastic 가 AGPLv3 추가 (blog). 8.16+ 부터 AGPL/SSPL/ES License 3-way 선택
2026ES 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분산 인덱스 + 검색 + 분석
KibanaUI, dashboard, dev tools, alerting
Logstash데이터 수집 + 변환 (옛). 현재 Ingest pipeline 이 대안
Beats가벼운 shipper. Elastic Agent 로 통합 진행 중
FleetElastic 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”

인덱스 결과:

TermPosting list
quickdoc1, doc3
browndoc1, doc2
foxdoc1
dogdoc2, doc3

검색 quick AND dog{doc1,doc3} ∩ {doc2,doc3} = doc3. O(1) 조회.

텍스트 필드 분석 파이프라인:

  1. Character filter: HTML 제거, 문자 변환
  2. Tokenizer: 공백/구두점 기준 분리
  3. 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 대안)
MLML 모델 실행 (유료 기능)

샤드 설계 원칙:

  • 샤드 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
Flushtranslog + 세그먼트 → 디스크 commit30분 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 GBJVM Compressed OOPs 활성 유지
Xms = Xmx런타임 확장 방지 (GC pause 최소화)
G1GC 기본 (7.0+)큰 heap 의 pause time 안정화

CAUTION

32 GB 이상 heap 설정 시 compressed OOPs 비활성 → 포인터 크기 2배 → 오히려 느려짐. 30 GB 이하 유지.

ES vs 다른 DB

ElasticSearchRDBMSMongoDBSolr
강점full-text search + analytics트랜잭션문서 + flexiblefull-text search
약점트랜잭션, write-heavyfull-text 약함검색 약함분산 운영 어려움
QueryDSL + ESQLSQLMQLDSL
Scalingshard + replicareplica + read splitshardshard
사용search, log, APMOLTP문서 + 모바일search (옛)

ES 8.x → 9.x 주요 변화

영역8.x9.x (2025+)
ESQL도입 (8.11)프로덕션 표준
Vectordense_vector + kNNquantization 자동, 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

  1. 오버샤딩 = 샤드 수 / 노드 > 20 이상이면 클러스터 상태 비대 → master 부하. 작은 인덱스 = 적은 샤드.
  2. dynamic mapping 방치 = 예측 못한 필드 자동 매핑 → 매핑 폭발 + 타입 충돌. dynamic: strict 로 관리.
  3. deep pagination (from: 10000+) = 메모리 + 속도 문제. search_after 또는 scroll API 사용.
  4. Index 를 Alias 없이 직접 노출 = 인덱스 재생성 (rolling) 불가. 처음부터 alias 로 추상화.
  5. snapshot 없는 운영 = 클러스터 다운 시 복구 방법 없음. Snapshot + ILM 필수.
  6. heap 32 GB 초과 = compressed OOPs 비활성 → 성능 역전. 30 GB 이하 유지.

관련 위키 (이 클러스터)

운영자 시점의 세부 페이지:

인접 위키

이 글의 용어 (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…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기