| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
- 성능
- CSS
- Performance
- database
- frontend
- architecture
- NextJS
- PostgreSQL
- Operations
- observability
- JavaScript
- Git
- Security
- aws
- Infra
- Debugging
- API
- DevOps
- Kubernetes
- CI
- auth
- reliability
- react
- HTTP
- web
- SRE
- backend
- 버전관리
- Ops
- version-control
- Today
- Total
고민보단 실천을
Elasticsearch/OpenSearch 성능/특성 정리: shards/heap/refresh/mapping으로 느림을 설명하기 본문
Elasticsearch/OpenSearch 성능/특성 정리: shards/heap/refresh/mapping으로 느림을 설명하기
Just-Do-It 2026. 3. 7. 13:59Elasticsearch/OpenSearch 성능/특성 정리: shards/heap/refresh/mapping으로 느림을 설명하기
이 글은 Elasticsearch/OpenSearch를 성능/운영 관점에서 길게 정리한 개인 노트입니다. 목표는 "지금 느린 이유"를 증거로 좁히고, 재발을 줄이는 체크리스트를 갖추는 것입니다.
전제: 성능은 DB만으로 결정되지 않습니다. 쿼리 패턴, 데이터 분포, 인덱스/스키마, 애플리케이션 트랜잭션 경계, 인프라(IO/네트워크)가 함께 결정합니다. 그래서 이 글은 '성능 모델(어디서 시간이 쓰이나) -> 설계/쿼리 -> 설정 -> 운영' 순서로 정리합니다.
이 DB를 언제 선택하나
정답은 항상 케이스 바이 케이스지만, 선택을 빠르게 만들기 위해 기준을 먼저 둡니다. 아래에 해당이 많을수록 이 DB를 고려할 만합니다.
- 텍스트 검색/필터/집계가 핵심인 서비스(로그, 검색, 분석)
- near real-time 색인(곧바로 검색 반영)이 필요할 때
- 매핑/샤드/ILM 같은 운영 개념을 팀이 감당할 수 있을 때
성능 모델: 어디서 시간이 쓰이나
성능 모델은 샤드 = Lucene 인덱스로 보면 됩니다. 샤드가 많아지면 병렬성은 늘 수 있지만 메모리/파일 핸들/오버헤드가 함께 증가합니다. 샤드는 너무 많아도, 너무 커도 문제입니다.
JVM 힙은 fielddata, query cache, segment metadata 등 다양한 메타에 쓰입니다. 힙이 부족하면 GC가 늘고 지연이 튑니다. refresh interval과 merge 정책도 색인/검색 지연을 좌우합니다.
핵심 용어 빠른 사전
성능/장애 분석에서 자주 쓰는 단어는 팀마다 다르게 이해되기 쉽습니다. 용어를 짧게 정의하고, 어떤 지표/증상과 연결되는지 같이 적어둡니다.
| 용어 | 설명 | 실무에서 연결되는 것 |
|---|---|---|
shard | Lucene 인덱스 단위 | 샤드 수/크기가 운영 난이도/지연을 결정 |
segment | Lucene 세그먼트 | merge/refresh와 연결, 너무 많으면 검색 오버헤드 |
refresh | 검색 가능 상태로 전환 | 짧으면 최신성↑ 대신 색인 비용↑ |
merge | 세그먼트 병합 | 병합이 몰리면 디스크/CPU로 지연 스파이크 |
heap/GC | JVM 힙과 가비지 컬렉션 | GC가 길면 검색 지연이 튐 |
mapping | 필드 타입/인덱싱 규칙 | fielddata 폭발/검색 품질과 연결 |
옵션/핵심 요소(3~6)
자주 부딪히는 핵심 요소를 표로 먼저 고정해 두면, 장애/튜닝 때 팀 커뮤니케이션이 빨라집니다.
| 항목 | 의미 | 언제 쓰는지(실무 상황) |
|---|---|---|
Shard | 검색/색인의 단위(Lucene index) | 데이터 분산과 병렬성을 결정할 때 |
Heap | JVM 힙 메모리 | GC/지연 스파이크를 줄이기 위한 핵심 리소스 |
refresh_interval | 검색 가능해지는 주기 | 색인/검색 지연 트레이드오프를 조정할 때 |
Segment Merge | 세그먼트 병합 | 디스크/검색 성능과 색인 성능의 균형 |
Mapping | 필드 타입/인덱싱 방식 | fielddata 폭발/검색 품질을 제어할 때 |
ILM/Rollover | 인덱스 수명주기 관리 | 시간 기반 인덱스를 안정적으로 운영할 때 |
실무 튜닝 포인트(설정/옵션별)
설정에는 정답이 없습니다. 워크로드(읽기/쓰기/동시성/데이터 크기) 기준으로 관측하고 조정합니다. 아래는 실무에서 가장 자주 만지는 레버를 '항목별'로 정리한 것입니다.
number_of_shards
의미: 샤드 수
언제 만지나: 데이터량/노드 수/검색 병렬성을 설계할 때
주의/트레이드오프: 초기에 과도하게 늘리면 오버헤드로 고생
number_of_replicas
의미: 복제 샤드 수
언제 만지나: 가용성과 읽기 확장을 원할 때
주의/트레이드오프: 복제가 늘면 색인 비용 증가
refresh_interval
의미: refresh 주기
언제 만지나: 색인이 많고 즉시 검색이 필요 없을 때 늘림
주의/트레이드오프: 늘리면 최신 데이터 검색 반영이 늦어짐
heap size
의미: JVM 힙 크기
언제 만지나: GC/지연 스파이크가 보일 때
주의/트레이드오프: 너무 크게 잡아도 GC가 느려질 수 있어 권장 범위 참고
fielddata
의미: 텍스트 필드 집계/정렬 메모리
언제 만지나: 집계/정렬은 keyword 필드로 분리
주의/트레이드오프: text에 fielddata를 켜면 힙이 터질 수 있음
bulk indexing
의미: 대량 색인 방식
언제 만지나: 색인 성능을 안정화할 때
주의/트레이드오프: bulk 크기/동시성 튜닝 필요
rollover/ILM
의미: 인덱스 교체/보관 정책
언제 만지나: 시간 기반 데이터 운영
주의/트레이드오프: 정책이 없으면 shard/segment 누적으로 운영이 무너짐
쿼리/스키마 설계에서 성능이 갈리는 지점
검색 성능을 안정화하려면 매핑부터 시작합니다. 문자열 필드는 보통 text(검색) + keyword(정렬/집계)로 나눠 쓰고, 불필요한 필드는 인덱싱을 끄는 게 좋습니다.
로그/이벤트처럼 시간 기반 데이터는 rollover/ILM로 인덱스를 주기적으로 교체하고, 오래된 인덱스는 merge/이관/삭제로 관리합니다.
{
"mappings": {
"properties": {
"message": { "type": "text" },
"message_keyword": { "type": "keyword" },
"created_at": { "type": "date" }
}
}
}POST /_bulk
{ "index": { "_index": "events" } }
{ "created_at": "2026-03-02T10:00:00Z", "message": "..." }진단 명령/쿼리 모음(바로 실행용)
장애 때는 문서 찾을 시간이 없습니다. 아래는 현장에서 자주 쓰는 '첫 5분' 진단 명령/쿼리만 모은 것입니다. 환경/권한에 따라 일부는 제한될 수 있습니다.
# 클러스터 상태
curl -s http://localhost:9200/_cluster/health?pretty
# 샤드/인덱스 현황
curl -s http://localhost:9200/_cat/indices?v
curl -s http://localhost:9200/_cat/shards?v
# 노드 JVM/힙
curl -s http://localhost:9200/_nodes/stats/jvm?pretty자주 하는 실수(운영/튜닝)
실수 체크리스트:
- 샤드 수를 과하게 잡아 메모리/오버헤드로 평생 고생한다
- text 필드에 fielddata를 켜서 힙을 터뜨린다(집계/정렬은 keyword로 분리)
- refresh_interval 기본값으로 대량 색인을 수행해 merge/refresh 폭주를 만든다
- ILM/rollover 없이 시간 기반 인덱스를 무한히 쌓아 운영을 무너뜨린다
- 힙/GC 지표 없이 검색 지연 원인을 쿼리만으로 단정한다
- bulk 크기/동시성을 조절하지 않고 색인 실패/지연을 반복한다
운영/모니터링 체크리스트
운영에서는 JVM heap/GC, 검색 지연(p99), 색인 속도/실패, segment/merge 시간, shard 수/크기를 핵심으로 봅니다. 지연 스파이크는 GC, merge, hot shard에서 시작하는 경우가 많습니다.
공통 체크리스트:
- 느린 쿼리 top N을 지속 수집(시간/호출수/총시간)
- 지연(p95/p99)과 오류율을 애플리케이션 지표와 함께 본다
- 캐시/메모리/디스크 IO 중 무엇이 병목인지 먼저 분리한다
- 복제/HA를 쓰면 일관성 요구가 높은 기능을 분리한다
- 튜닝/변경 후에는 동일 조건으로 재측정해 회귀를 막는다
트러블슈팅 루틴(순서 고정)
장애 때는 선택지가 너무 많아서 흔히 길을 잃습니다. 아래 순서를 팀 표준으로 정해두면, 원인 추적이 빨라지고 '감으로 설정만 만지는' 일을 줄일 수 있습니다.
1) 지연 스파이크 시간대의 GC/heap을 확인한다
2) shard 수/크기(특히 hot shard)를 확인한다
3) refresh/merge가 과도한지 본다
4) 매핑에서 fielddata 폭발/keyword 누락이 없는지 확인한다
5) ILM/rollover로 인덱스 수명주기를 정리한다
6) 대량 색인은 bulk + refresh_interval 조정으로 분리한다문제 상황(정확히 1개)
상황 -> 검색 지연이 평소 50ms인데, 하루에 몇 번씩 2~3초로 튄다.
원인 -> 힙 압박으로 GC가 길어지거나, 세그먼트 merge가 디스크/CPU를 점유해 검색이 밀렸다.
해결 -> heap/GC와 merge 지표를 확인하고 샤드/ILM 정책을 정리하며 refresh_interval과 bulk 방식을 조정한다.
예방 팁 -> 샤드/인덱스 정책(ILM)을 초기부터 정하고 heap/GC/merge를 알람으로 관리한다.
참고/출처
정확한 동작/버전별 차이는 공식 문서를 기준으로 확인합니다. 실무에서는 버전 차이가 곧 성능/장애 차이입니다.
'DB' 카테고리의 다른 글
| MongoDB 성능/특성 정리: 인덱스/Working Set/aggregation으로 느린 조회 잡기 (0) | 2026.03.07 |
|---|---|
| MariaDB 성능/특성 정리: MySQL 호환 + 옵티마이저/복제 운영 포인트 (0) | 2026.03.07 |
| Amazon DynamoDB 성능/특성 정리: 키 설계로 핫 파티션/비용/스로틀링 줄이기 (0) | 2026.03.06 |
| ClickHouse 성능/특성 정리: 컬럼형+MergeTree(ORDER BY/partition)로 OLAP 성능 만들기 (0) | 2026.03.06 |
| Apache Cassandra 성능/특성 정리: partition key/모델링/tombstones/compaction (0) | 2026.03.06 |
