Elasticsearch란 무엇인가 – 개념부터 동작 원리, 실전 활용법까지 완벽 정리


Elasticsearch란 무엇인지, 이름은 들어봤지만 “그냥 빠른 검색 DB 아닌가요?”라고 넘겼던 분들이 많습니다. 실제로 쿠팡의 상품 검색, 네이버의 뉴스 검색, 슬랙의 메시지 검색, 깃허브의 코드 검색 뒤에는 모두 Elasticsearch가 있습니다. 단순한 데이터베이스가 아니라, 수억 건의 데이터 속에서 밀리초 단위로 원하는 정보를 찾아내는 분산 검색 엔진입니다. 이 글에서는 Elasticsearch가 왜 필요한지부터 내부 동작 원리, 실전 쿼리 작성법까지 코드와 다이어그램으로 낱낱이 설명합니다. 끝까지 읽고 나면 Elasticsearch를 언제, 왜, 어떻게 써야 하는지 명확하게 판단할 수 있습니다.


목차

  1. Elasticsearch란 무엇인가 – 기초 개념 정리
  2. Elasticsearch 핵심 원리 – 역색인과 분산 구조
  3. Elasticsearch가 가져다주는 장점과 적합한 사용 사례
  4. Elasticsearch 사용 시 주의점과 한계
  5. 실전 단계별 활용법 – 설치부터 쿼리 작성까지
  6. 전문가 관점 – ELK 스택과 추천 학습 도구

1. Elasticsearch란 무엇인가 – 기초 개념 정리

Elasticsearch란 Apache Lucene 기반으로 구축된 오픈소스 분산 검색·분석 엔진입니다. 2010년 Shay Banon이 개발하였고, 현재는 Elastic NV가 관리합니다. JSON 형태의 문서를 저장하고, RESTful API로 조회·분석하며, 수평 확장이 가능한 분산 아키텍처를 기본으로 채택합니다.

왜 관계형 DB로는 부족한가

검색 기능을 MySQL이나 PostgreSQL 같은 관계형 DB(RDB)로만 구현하면 다음과 같은 한계에 금방 부딪힙니다.

sql

-- RDB의 LIKE 검색 – 인덱스를 타지 못해 전체 테이블 스캔 발생
SELECT * FROM products
WHERE name LIKE '%무선 블루투스 이어폰%';

이 쿼리는 레코드가 100만 건만 넘어가도 수 초 이상 걸리기 시작합니다. 오타 허용(블루투수 → 블루투스)도 안 되고, 동의어 처리(이어폰 = 이어버드)도 어렵습니다. 관련도 순 정렬도 불가능합니다.

Elasticsearch는 이 문제를 역색인(Inverted Index) 구조로 해결합니다. 검색어가 어느 문서에 있는지 미리 색인을 만들어 두기 때문에, 수억 건의 데이터에서도 밀리초 단위의 풀텍스트 검색이 가능합니다.

핵심 용어 정리 – RDB와 비교

Elasticsearch를 처음 접할 때 가장 헷갈리는 것이 용어입니다. RDB와 대응시켜 이해하면 훨씬 빠릅니다.

RDBElasticsearch설명
DatabaseIndex데이터를 저장하는 최상위 단위
TableType → IndexES 7.x 이후 Type 개념 폐기
RowDocument실제 데이터 한 건 (JSON)
ColumnField도큐먼트의 각 속성
SchemaMapping필드 타입 및 색인 방식 정의
IndexInverted Index검색을 위한 색인 구조
JOINNested / Join Field제한적으로 지원

중요: Elasticsearch 7.x부터 _type 개념이 제거되었습니다. 하나의 인덱스에 하나의 도큐먼트 타입만 존재합니다.

도큐먼트(Document)란?

Elasticsearch에서 데이터의 최소 단위는 도큐먼트입니다. JSON 형식으로 저장되며, 각 도큐먼트는 고유한 _id를 가집니다.

json

// 상품 도큐먼트 예시
{
  "_index": "products",
  "_id": "1001",
  "_source": {
    "name": "소니 WH-1000XM5 무선 블루투스 헤드폰",
    "brand": "Sony",
    "category": "헤드폰",
    "price": 389000,
    "rating": 4.8,
    "tags": ["노이즈캔슬링", "무선", "블루투스", "프리미엄"],
    "description": "업계 최고 수준의 노이즈 캔슬링과 30시간 배터리 지속 시간",
    "inStock": true,
    "createdAt": "2024-03-15T09:00:00Z"
  }
}

RDB의 행(Row)과 달리, 도큐먼트는 중첩 객체와 배열을 자연스럽게 표현할 수 있어 복잡한 데이터 구조를 하나의 도큐먼트로 표현하기 유리합니다.


2. Elasticsearch 핵심 원리 – 역색인과 분산 구조

역색인(Inverted Index) – 검색 속도의 비밀

Elasticsearch가 빠른 이유의 핵심은 역색인(Inverted Index) 구조입니다. 일반 색인(Forward Index)이 “문서 → 단어 목록”을 기록한다면, 역색인은 반대로 “단어 → 해당 단어가 등장하는 문서 목록”을 기록합니다.

책의 맨 뒤 찾아보기(색인) 페이지를 생각해 보세요. “캡슐화”라는 단어가 몇 페이지에 나오는지 바로 찾을 수 있습니다. 처음부터 전체 책을 읽지 않아도 됩니다. Elasticsearch의 역색인이 정확히 이 원리입니다.

[문서 원문]
Doc 1: "무선 블루투스 이어폰 추천"
Doc 2: "블루투스 헤드폰 노이즈캔슬링"
Doc 3: "무선 헤드폰 충전 방법"

[역색인 구조]
토큰(단어)      →  문서 ID 목록
─────────────────────────────
"무선"          →  [Doc 1, Doc 3]
"블루투스"      →  [Doc 1, Doc 2]
"이어폰"        →  [Doc 1]
"추천"          →  [Doc 1]
"헤드폰"        →  [Doc 2, Doc 3]
"노이즈캔슬링"  →  [Doc 2]
"충전"          →  [Doc 3]
"방법"          →  [Doc 3]

“블루투스 헤드폰”으로 검색하면 역색인에서 “블루투스” → [Doc 1, Doc 2], “헤드폰” → [Doc 2, Doc 3]을 즉시 찾고, 교집합인 Doc 2를 가장 관련성 높은 결과로 반환합니다. 전체 문서를 스캔할 필요가 없습니다.

애널라이저(Analyzer) – 텍스트를 토큰으로 분해

역색인을 만들기 위해 텍스트를 단어(토큰) 단위로 분해하는 과정을 분석(Analysis) 이라고 하고, 이를 담당하는 컴포넌트가 애널라이저(Analyzer) 입니다.

애널라이저 처리 흐름:
원문 텍스트
    ↓
[Character Filter]    불필요한 문자 제거 (HTML 태그, 특수문자 등)
    ↓
[Tokenizer]           텍스트를 토큰으로 분리 (공백, 형태소 기준 등)
    ↓
[Token Filter]        토큰 정규화 (소문자 변환, 동의어 처리, 불용어 제거 등)
    ↓
역색인에 저장

한국어 처리에는 Nori 애널라이저가 가장 많이 사용됩니다. Elastic에서 공식 제공하는 한국어 형태소 분석기로, “삼성전자 갤럭시폰”을 “삼성전자”, “갤럭시”, “폰”으로 분리합니다.

클러스터·노드·샤드·레플리카 – 분산 구조 이해

Elasticsearch는 처음부터 분산 시스템으로 설계되었습니다. 구성 요소를 계층적으로 이해하면 전체 구조가 명확해집니다.

┌──────────────────────────────────────────────┐
│              Cluster (my-cluster)            │
│                                              │
│  ┌─────────────┐     ┌─────────────┐         │
│  │   Node 1    │     │   Node 2    │  ...    │
│  │  (Master)   │     │  (Data)     │         │
│  │             │     │             │         │
│  │ ┌─────────┐ │     │ ┌─────────┐ │         │
│  │ │Shard P0 │ │     │ │Shard R0 │ │         │
│  │ │(Primary)│ │     │ │(Replica)│ │         │
│  │ └─────────┘ │     │ └─────────┘ │         │
│  │ ┌─────────┐ │     │ ┌─────────┐ │         │
│  │ │Shard R1 │ │     │ │Shard P1 │ │         │
│  │ │(Replica)│ │     │ │(Primary)│ │         │
│  │ └─────────┘ │     │ └─────────┘ │         │
│  └─────────────┘     └─────────────┘         │
└──────────────────────────────────────────────┘
  • 클러스터(Cluster): 하나 이상의 노드가 모인 집합. 동일한 클러스터 이름으로 묶입니다.
  • 노드(Node): 클러스터를 구성하는 개별 Elasticsearch 인스턴스(서버). 역할에 따라 Master, Data, Coordinating 노드 등으로 구분됩니다.
  • 샤드(Shard): 인덱스를 물리적으로 분할한 단위. 인덱스를 여러 샤드로 나눠 여러 노드에 분산 저장합니다. 수평 확장이 가능한 이유입니다.
  • 프라이머리 샤드(Primary Shard): 실제 데이터가 저장되는 원본 샤드.
  • 레플리카 샤드(Replica Shard): 프라이머리 샤드의 복사본. 노드 장애 시 데이터 유실을 방지하고, 읽기 요청을 분산 처리하여 성능을 높입니다.
// 샤드 설정 예시: 프라이머리 3개, 레플리카 1세트
PUT /products
{
  "settings": {
    "number_of_shards": 3,    // 프라이머리 샤드 3개로 데이터 분산
    "number_of_replicas": 1   // 각 프라이머리마다 레플리카 1개
  }
}
// 총 샤드 수: 3 (Primary) + 3 (Replica) = 6개

3. Elasticsearch가 가져다주는 장점과 적합한 사용 사례

핵심 장점

① 밀리초 단위 풀텍스트 검색 역색인 구조 덕분에 수억 건의 도큐먼트에서도 밀리초 단위의 검색이 가능합니다. 오타 허용(Fuzzy Search), 동의어 처리, 부분 일치, 자동완성(Autocomplete)까지 기본으로 지원합니다.

② 수평 확장(Horizontal Scaling) 노드를 추가하는 것만으로 클러스터의 저장 용량과 처리량을 선형적으로 확장할 수 있습니다. 수 TB에서 수 PB까지 운영하는 사례가 있습니다. 단일 노드의 성능 한계에 도달하면 장비를 교체(수직 확장)하는 RDB와 근본적으로 다른 확장 전략입니다.

③ 실시간에 가까운 색인 도큐먼트를 저장하면 기본 1초(refresh interval) 안에 검색 가능한 상태가 됩니다. Near Real-Time(NRT) 검색을 지원합니다.

④ 강력한 집계(Aggregation) 단순 검색을 넘어 데이터 분석도 가능합니다. SQL의 GROUP BYCOUNTAVGMAX 등에 해당하는 집계를 JSON 쿼리 하나로 표현할 수 있으며, 다단계 중첩 집계도 지원합니다.

⑤ 스키마리스(Schema-less) 지원 매핑을 명시하지 않아도 도큐먼트를 저장하면 Elasticsearch가 필드 타입을 자동으로 추론(Dynamic Mapping)합니다. 초기 개발 속도가 빠릅니다. 단, 운영 환경에서는 명시적 매핑 설정을 권장합니다.

적합한 사용 사례

사용 사례구체적 예시
상품·콘텐츠 검색이커머스 상품 검색, 뉴스·블로그 검색
로그 분석서버 로그, 애플리케이션 오류 로그, 보안 이벤트 분석
실시간 모니터링인프라 메트릭, APM, 애플리케이션 성능 추적
자동완성·추천검색창 자동완성, 연관 검색어 추천
지리 공간 검색반경 N km 내 매장 검색, 위치 기반 필터링
보안 분석(SIEM)침해 탐지, 이상 행동 분석

4. Elasticsearch 사용 시 주의점과 한계

트랜잭션 미지원 – 데이터 정합성 주의

Elasticsearch는 ACID 트랜잭션을 지원하지 않습니다. 여러 도큐먼트를 원자적으로 업데이트하거나 롤백하는 것이 불가능합니다. 주문, 결제, 재고 같은 정합성이 중요한 데이터는 반드시 RDB(MySQL, PostgreSQL)를 주 저장소로 사용하고, Elasticsearch는 검색·조회 목적의 보조 저장소로 활용하는 패턴이 실무 표준입니다.

[실무 권장 아키텍처]

사용자 요청
    │
    ├─── 쓰기(주문, 결제) ──→ RDB (MySQL) ──→ CDC / 메시지큐 ──→ Elasticsearch 동기화
    │
    └─── 검색(상품 조회) ──→ Elasticsearch

Near Real-Time – 즉각적 반영이 아님

도큐먼트를 저장해도 기본 설정(refresh_interval: 1s)에서는 1초 후에야 검색 결과에 반영됩니다. 실시간성이 절대적으로 필요한 금융 거래 데이터나 재고 수량 같은 정보는 Elasticsearch 단독으로 처리하기 어렵습니다.

매핑 변경의 어려움

한번 생성된 인덱스의 기존 필드 매핑은 변경이 불가능합니다. 예를 들어 text 타입으로 색인된 필드를 keyword 타입으로 바꾸려면, 새 인덱스를 생성하고 전체 데이터를 재색인(Reindex) 해야 합니다. 데이터가 수억 건이라면 재색인 작업이 수 시간에서 수십 시간이 걸릴 수 있습니다. 초기 매핑 설계를 신중하게 해야 하는 이유입니다.

json

// 잘못 설계된 매핑을 변경하려면 재색인 필요
POST /_reindex
{
  "source": { "index": "products_v1" },
  "dest":   { "index": "products_v2" }
}
// 이후 products_v2를 products 별칭(alias)으로 전환

메모리 사용량과 힙 설정

Elasticsearch는 JVM 기반으로 동작하며, 힙 메모리 설정이 성능에 직결됩니다. 너무 적으면 OOM(Out of Memory) 오류, 너무 많으면 GC 정지 시간이 길어집니다. 공식 권장은 물리 메모리의 50% 이하, 최대 32GB입니다.

yaml

# jvm.options 설정 예시
-Xms16g   # 최소 힙
-Xmx16g   # 최대 힙 (min = max로 설정 권장 – GC 오버헤드 최소화)

Split Brain 문제

클러스터 노드 간 네트워크가 분리(파티션)되면 각 파티션이 독립적인 마스터를 선출하여 서로 다른 데이터를 기록하는 Split Brain 현상이 발생할 수 있습니다. discovery.zen.minimum_master_nodes 설정(또는 ES 7.x의 cluster.initial_master_nodes)으로 쿼럼을 설정해 이 문제를 예방해야 합니다.


5. 실전 단계별 활용법 – 설치부터 쿼리 작성까지

Step 1. Docker로 빠르게 시작하기

yaml

# docker-compose.yml
version: '3.8'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.13.0
    container_name: elasticsearch
    environment:
      - discovery.type=single-node          # 단일 노드 개발 모드
      - xpack.security.enabled=false        # 개발 환경 보안 비활성화
      - ES_JAVA_OPTS=-Xms1g -Xmx1g
    ports:
      - "9200:9200"
    volumes:
      - es-data:/usr/share/elasticsearch/data

  kibana:
    image: docker.elastic.co/kibana/kibana:8.13.0
    container_name: kibana
    ports:
      - "5601:5601"
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    depends_on:
      - elasticsearch

volumes:
  es-data:

bash

docker-compose up -d
# Elasticsearch: http://localhost:9200
# Kibana:        http://localhost:5601

Step 2. 인덱스 생성 및 매핑 설정

json

PUT /products
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0,
    "analysis": {
      "analyzer": {
        "korean_analyzer": {
          "type": "custom",
          "tokenizer": "nori_tokenizer",
          "filter": ["lowercase", "nori_part_of_speech"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "korean_analyzer",
        "fields": {
          "keyword": { "type": "keyword" }  // 정렬·집계용 keyword 서브필드
        }
      },
      "brand":    { "type": "keyword" },    // 정확 일치 검색
      "category": { "type": "keyword" },
      "price":    { "type": "double" },
      "rating":   { "type": "float" },
      "tags":     { "type": "keyword" },
      "description": {
        "type": "text",
        "analyzer": "korean_analyzer"
      },
      "inStock":    { "type": "boolean" },
      "createdAt":  { "type": "date" }
    }
  }
}

Step 3. 도큐먼트 색인(저장)

json

// 단일 도큐먼트 색인
POST /products/_doc/1001
{
  "name": "소니 WH-1000XM5 무선 블루투스 헤드폰",
  "brand": "Sony",
  "category": "헤드폰",
  "price": 389000,
  "rating": 4.8,
  "tags": ["노이즈캔슬링", "무선", "블루투스", "프리미엄"],
  "description": "업계 최고 수준의 노이즈 캔슬링과 30시간 배터리 지속 시간",
  "inStock": true,
  "createdAt": "2024-03-15T09:00:00Z"
}

// 벌크 색인 – 대량 데이터 적재 시 사용 (권장)
POST /products/_bulk
{ "index": { "_id": "1002" } }
{ "name": "애플 AirPods Pro 2세대", "brand": "Apple", "category": "이어폰", "price": 359000, "rating": 4.7, "tags": ["노이즈캔슬링", "무선", "애플"], "inStock": true, "createdAt": "2024-01-10T09:00:00Z" }
{ "index": { "_id": "1003" } }
{ "name": "삼성 갤럭시 버즈2 프로", "brand": "Samsung", "category": "이어폰", "price": 199000, "rating": 4.5, "tags": ["노이즈캔슬링", "무선", "삼성"], "inStock": true, "createdAt": "2024-02-20T09:00:00Z" }

Step 4. 다양한 쿼리 작성

① 기본 풀텍스트 검색

json

GET /products/_search
{
  "query": {
    "match": {
      "name": "블루투스 헤드폰"  // 형태소 분석 후 검색
    }
  }
}

② 복합 조건 검색 (bool 쿼리)

json

GET /products/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "name": "헤드폰" } }         // 반드시 포함 (점수 영향)
      ],
      "filter": [
        { "term":  { "inStock": true } },          // 재고 있는 상품만 (점수 무관)
        { "range": { "price": { "lte": 400000 } } } // 40만원 이하
      ],
      "should": [
        { "term": { "tags": "노이즈캔슬링" } }     // 있으면 점수 가산
      ],
      "must_not": [
        { "term": { "brand": "Unknown" } }         // 제외할 조건
      ]
    }
  },
  "sort": [
    { "_score": { "order": "desc" } },   // 관련도 점수 내림차순
    { "rating": { "order": "desc" } }    // 평점 내림차순 (2차 정렬)
  ],
  "from": 0,   // 페이지네이션 시작 오프셋
  "size": 10   // 반환할 도큐먼트 수
}

③ 자동완성 (Prefix 검색)

json

GET /products/_search
{
  "query": {
    "match_phrase_prefix": {
      "name": "블루투"   // "블루투스", "블루투스 헤드폰" 등 자동완성
    }
  }
}

④ 집계(Aggregation) – 카테고리별 평균 가격

json

GET /products/_search
{
  "size": 0,  // 도큐먼트는 필요 없고 집계 결과만 반환
  "aggs": {
    "by_category": {
      "terms": { "field": "category" },           // 카테고리별 그룹핑
      "aggs": {
        "avg_price": { "avg": { "field": "price" } },   // 평균 가격
        "max_rating": { "max": { "field": "rating" } }  // 최고 평점
      }
    }
  }
}

Step 5. Spring Data Elasticsearch 연동

xml

<!-- pom.xml -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

yaml

# application.yml
spring:
  elasticsearch:
    uris: http://localhost:9200
    connection-timeout: 5s
    socket-timeout: 30s

java

// 도큐먼트 엔티티 정의
@Document(indexName = "products")
@Setting(settingPath = "elasticsearch/settings.json")
public class ProductDocument {

    @Id
    private String id;

    @Field(type = FieldType.Text, analyzer = "korean_analyzer")
    private String name;

    @Field(type = FieldType.Keyword)
    private String brand;

    @Field(type = FieldType.Keyword)
    private String category;

    @Field(type = FieldType.Double)
    private double price;

    @Field(type = FieldType.Float)
    private float rating;

    @Field(type = FieldType.Boolean)
    private boolean inStock;

    @Field(type = FieldType.Date, format = DateFormat.date_time)
    private LocalDateTime createdAt;

    // getter, setter, builder...
}

// Repository 정의
public interface ProductSearchRepository
        extends ElasticsearchRepository<ProductDocument, String> {

    // 메서드 이름으로 쿼리 자동 생성
    List<ProductDocument> findByBrandAndInStockTrue(String brand);
    List<ProductDocument> findByPriceBetween(double min, double max);
}

// 서비스 레이어 – NativeQuery로 복잡한 쿼리 처리
@Service
public class ProductSearchService {

    private final ElasticsearchOperations operations;

    public ProductSearchService(ElasticsearchOperations operations) {
        this.operations = operations;
    }

    public SearchHits<ProductDocument> searchProducts(String keyword,
                                                       double maxPrice,
                                                       String category) {
        Query query = NativeQuery.builder()
            .withQuery(q -> q
                .bool(b -> b
                    .must(m -> m.match(mt -> mt.field("name").query(keyword)))
                    .filter(f -> f.range(r -> r.field("price").lte(JsonData.of(maxPrice))))
                    .filter(f -> f.term(t -> t.field("category").value(category)))
                    .filter(f -> f.term(t -> t.field("inStock").value(true)))
                )
            )
            .withSort(Sort.by(Sort.Direction.DESC, "_score"))
            .withPageable(PageRequest.of(0, 10))
            .build();

        return operations.search(query, ProductDocument.class);
    }
}

6. 전문가 관점 – ELK 스택과 추천 학습 도구

ELK 스택 – Elasticsearch의 생태계

Elasticsearch란 단독으로도 강력하지만, ELK 스택과 함께 사용할 때 진가가 발휘됩니다.

[데이터 흐름]

애플리케이션 로그
서버 메트릭       →  Logstash / Beats  →  Elasticsearch  →  Kibana (시각화)
보안 이벤트                (수집·변환)        (저장·검색)      (대시보드·알림)
  • Logstash: 다양한 소스에서 데이터를 수집하고 변환·정제하여 Elasticsearch에 전송하는 데이터 파이프라인.
  • Kibana: Elasticsearch 데이터를 시각화하는 웹 UI. 대시보드, 차트, 로그 탐색, ML 이상 탐지 등을 제공합니다.
  • Beats: Logstash보다 경량화된 데이터 수집 에이전트. Filebeat(로그), Metricbeat(메트릭), Packetbeat(네트워크) 등이 있습니다.

최근에는 Logstash 대신 경량화된 Elastic Agent나 OpenTelemetry Collector를 사용하는 추세입니다.

Elasticsearch vs 경쟁 기술 비교

항목ElasticsearchSolrOpenSearchMeilisearch
관리 주체Elastic NVApacheAWSMeili
라이선스SSPL / ElasticApache 2.0Apache 2.0MIT
사용 편의성중간낮음중간높음
관리형 클라우드Elastic Cloud없음AWS OpenSearchMeilisearch Cloud
한국어 지원Nori (공식)커뮤니티Nori 포크제한적
적합 규모대규모대규모대규모중소규모

AWS는 Elasticsearch의 라이선스 변경(Apache 2.0 → SSPL) 이후 OpenSearch를 포크하여 독자 운영합니다. AWS 환경이라면 Amazon OpenSearch Service 사용을 고려할 수 있습니다.

추천 학습 도구 및 리소스

도구 / 리소스용도
Kibana Dev ToolsREST API 쿼리 테스트 (가장 추천)
Elastic 공식 문서 (elastic.co/guide)공식 레퍼런스, API 명세
Elastic 공식 교육 (elastic.co/training)무료 온라인 강의 제공
elasticsearch-head클러스터 상태 시각화 Chrome 확장
Elasticvue클러스터 관리 GUI
인프런 – Elasticsearch 강의한국어 실습 중심 강의

면접 대비 핵심 답변

“Elasticsearch가 RDB보다 검색이 빠른 이유는?” 역색인(Inverted Index) 구조 때문입니다. 미리 단어-문서 매핑 테이블을 만들어 두기 때문에 검색 시 전체 데이터를 스캔하지 않아도 됩니다. RDB의 LIKE '%keyword%' 검색은 인덱스를 활용하지 못해 Full Table Scan이 발생하지만, Elasticsearch는 역색인에서 해당 토큰이 포함된 문서 목록을 즉시 조회합니다.

“Elasticsearch와 RDB를 함께 사용하는 이유는?” Elasticsearch는 트랜잭션, 정확한 조인, 강한 정합성을 지원하지 않습니다. 주문·결제·재고처럼 ACID가 필요한 데이터는 RDB에 저장하고, 검색·조회 성능이 필요한 부분만 Elasticsearch로 동기화하는 이중 저장소(Dual Write) 패턴이 실무 표준입니다.


결론

Elasticsearch란 역색인 기반의 분산 검색 엔진으로, 수억 건의 데이터에서 밀리초 단위의 풀텍스트 검색·집계를 가능하게 하는 현대 백엔드 인프라의 핵심 기술입니다. 트랜잭션 미지원, 매핑 변경의 어려움 등 명확한 한계가 있으므로 RDB와 상호 보완적으로 활용하는 것이 실무 표준입니다. 오늘 배운 개념을 바탕으로 Docker로 Elasticsearch를 로컬에 띄우고, Kibana Dev Tools에서 직접 도큐먼트를 색인하고 검색 쿼리를 날려보세요. 눈으로 결과를 확인하는 순간 개념이 완전히 내 것이 됩니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다