ElasticSearch 아키텍처 이해 및 구축 실습

리본24·2025년 3월 3일
post-thumbnail

1. ElasticSearch 개요 및 아키텍처

1.1 ElasticSearch란?

  • 오픈소스 기반의 분산형 검색 및 분석 엔진입니다.
  • JSON 기반 RESTful API를 제공하여 다양한 애플리케이션과 쉽게 연동 가능합니다.
  • Apache Lucene을 기반으로 개발된 고성능 검색 엔진입니다.
    • Apache Lucene은 고성능, 확장 가능한 오픈소스 검색 라이브러리로, Java 기반으로 개발되었습니다.
    • 검색 엔진의 핵심 기능을 제공하며, 텍스트 기반의 색인(Indexing) 및 검색(Search) 기능을 수행합니다.
    • Lucene은 독립적인 검색 라이브러리이지만, ElasticSearch, Solr 같은 검색 엔진의 핵심 컴포넌트로 사용됩니다.
    • ElasticSearch는 Lucene을 기반으로 구축되었으며, Lucene의 강력한 검색 기능을 RESTful API로 제공하는 구조입니다.

1.1.1 Apache Lucene의 주요 특징

  • 텍스트 색인 및 검색
    • Lucene은 문서를 토큰화(Tokenization) 하고, 역색인(Inverted Index) 구조를 생성하여 빠른 검색이 가능하도록 합니다.
  • 강력한 검색 기능
    • Full-Text Search (단어, 문장, 구문 검색)
      • Full-Text Search(전문 검색)는 문서나 데이터에서 텍스트 기반으로 원하는 정보를 빠르게 검색하는 방법입니다.
      • 단순한 문자열 검색이 아니라, 자연어 처리 기법을 적용하여 보다 정확한 검색 결과를 제공합니다.
      • Full-Text Search의 특징
        1. 단순한 문자열 검색과 차별화됨

          • 일반적인 LIKE 검색(SQL WHERE name LIKE '%keyword%')은 해당 문자열이 포함된 레코드를 검색하지만, Full-Text Search는 의미적으로 관련 있는 단어까지 검색 가능합니다.
        2. 역색인(Inverted Index) 방식 사용

          • 문서 전체를 검색하는 것이 아니라, 단어 단위로 인덱스를 생성하여 빠르게 검색할 수 있습니다.
          • 기존 색인 방식(Sequential Search): 문서를 처음부터 끝까지 순차적으로 탐색 → 속도가 느림
          • 역색인 방식: 단어를 기준으로 인덱스를 생성하고, 해당 단어가 포함된 문서를 매핑 → 검색 속도 향상
          • 예) 문서 데이터
          문서 ID내용
          1"Elasticsearch is a search engine"
          2"A search engine is powerful"
          • 예) 역색인 구조
          단어포함된 문서 ID
          Elasticsearch1
          search1, 2
          engine1, 2
          powerful2
          • 이와 같이 문서 1과 2에서 해당 단어를 포함하는 문서를 빠르게 찾을 수 있습니다.
        3. 토큰화(Tokenization) 및 텍스트 분석

          • 문장을 단어(Token) 단위로 분리하고, 불필요한 단어(Stop Words)를 제거하며, 동의어 및 어근(Stem) 처리를 수행합니다.
          • 예)
          "Elasticsearch is a distributed search engine"
          • 토큰화 결과
            • ["elasticsearch", "distributed", "search", "engine"]
            • (불필요한 단어 is, a 제거됨)
          • 어근 분석(Stemming)
            • 동일한 의미의 단어를 하나로 통합하여 검색 성능을 향상시키는 기법입니다
            • 예)
              • "running", "runner", "runs" → "run"

              • "better", "best" → "good"

                ElasticSearch에서는 Stemmer Analyzer를 사용하여 이를 처리할 수 있습니다.

        4. Ranking(가중치 부여) 및 검색 결과 정렬

          • 검색어와 문서 간의 관련성(검색 점수, TF-IDF, BM25)을 기반으로 검색 결과 정렬이 가능합니다.
          • TF-IDF: 특정 단어가 문서에서 얼마나 중요한지를 평가하는 알고리즘
          • BM25: TF-IDF를 개선한 알고리즘으로, 문서 길이에 따라 가중치를 조정하여 검색 결과의 품질을 향상시킴
    • Boolean Query (AND, OR, NOT 연산자 지원)
      • Boolean Query(부울 쿼리)는 여러 개의 검색 조건을 조합하여 더욱 정교한 검색을 수행할 수 있도록 하는 ElasticSearch의 기능입니다.
      • SQL에서 AND, OR, NOT 연산자를 사용하여 데이터를 필터링하는 것과 유사합니다.
      • 주요 특징
        • 다양한 검색 조건을 조합하여 정확한 검색 결과 제공

        • 복합적인 검색 로직 구현 가능

        • AND, OR, NOT과 같은 논리 연산을 활용하여 필터링 수행

          조건 키워드역할
          must모든 조건을 만족해야 검색 결과 포함 (AND 연산)
          should하나 이상의 조건을 만족하면 포함 (OR 연산)
          must_not이 조건에 해당하는 문서를 제외 (NOT 연산)
          filter검색 성능 최적화를 위한 필터 적용 (캐싱 가능)
    • Wildcard 검색 (?, *``와일드카드 사용 가능)
      • Wildcard 검색특정 패턴에 일치하는 단어를 검색하는 방법으로, ElasticSearch에서 부분 일치 검색(Partial Match)을 수행할 때 사용됩니다. SQL의 LIKE '%keyword%'와 유사하지만, ElasticSearch에서는 역색인(Inverted Index) 을 활용하여 훨씬 더 빠르고 효율적인 검색을 제공합니다.
      • 주의
        • Wildcard 검색은 검색 성능에 영향을 줄 수 있으므로, 지나치게 광범위한 패턴을 사용하는 것은 권장되지 않습니다.
      • 주요 특징
        • 특정 패턴을 포함하는 단어 검색 가능
        • SQL의 LIKE 검색보다 성능이 뛰어남
        • *? 와일드카드 사용 가능
        • ElasticSearch는 기본적으로 대소문자를 구분
        • 대소문자를 구분하지 않으려면 lowercase 필터 필요
          와일드카드 기호설명예제검색 결과
          *0개 이상의 문자와 일치te*test, team, text
          ?단일 문자 하나와 일치te?ttest, text (but not teet)
    • Proximity 검색 (두 단어 사이의 거리를 고려한 검색)
      • Proximity 검색(근접 검색)은 검색어 간의 거리를 고려하여 검색 결과를 반환하는 방식입니다.
      • 즉, 두 개 이상의 단어가 특정 거리 내에 존재하는 경우에만 검색 결과를 반환합니다.
      • 일반적인 Full-Text 검색과 다르게, 단어 간의 위치를 고려한 검색을 수행합니다.
      • Proximity 검색이 필요한 이유
        1. 유연한 검색 가능
          • 단순한 키워드 검색보다 단어 간의 관계를 고려하여 검색 정확도 향상
          • 예: "quick brown fox""brown quick fox" 를 같은 의미로 검색
        2. 문서 내 단어 순서가 다른 경우에도 검색 가능
          • "fast car""car fast" 도 검색 가능
        3. 일정 거리 내에서만 단어가 함께 나타날 경우 검색
          • "Artificial Intelligence""Intelligence Artificial"을 검색할 때 단어 간 거리를 제한 가능
    • Ranking (TF-IDF, BM25) (검색 결과의 중요도 평가)
      • Ranking(랭킹)은 검색 결과에서 문서의 중요도(Relevance Score)를 평가하여, 사용자가 원하는 정보를 우선적으로 제공하는 기능입니다.
      • ElasticSearch는 TF-IDF(Term Frequency - Inverse Document Frequency)BM25(Best Matching 25) 알고리즘을 사용하여 검색 결과의 순위를 정합니다.
      • TF-IDF는 문서 내에서 단어의 중요도를 계산하는 대표적인 검색 알고리즘입니다.

        - **TF(Term Frequency, 단어 빈도수)**TF = 문서 내 전체 단어 개수특정 단어가 해당 문서에 등장한 횟수
            - 특정 문서에서 특정 단어가 등장하는 횟수
            - 문서 내에서 자주 등장할수록 중요도가 높아짐
            - 하지만, 모든 문서에서 많이 등장하는 단어(예: "the", "is")는 중요도가 낮아야 함
                

        - **IDF(Inverse Document Frequency, 역문서 빈도수)**IDF=log(해당 단어를 포함한 문서 수+1전체 문서 수​)
            - 특정 단어가 전체 문서에서 얼마나 희귀한지를 계산
            - 흔한 단어는 점수를 낮추고, 특정 문서에서만 자주 나오는 단어는 점수를 높임
                

  • * 역색인(Inverted Index) 방식 사용
    • Lucene은 역색인(Inverted Index) 방식을 사용하여 검색 속도를 최적화합니다.
    • 일반적인 데이터베이스는 순차적 검색(Sequential Search) 을 사용하지만, Lucene은 역색인을 활용하여 빠르게 검색할 수 있습니다.
    • 역색인은 단어와 해당 단어가 포함된 문서 ID 목록을 매핑하는 데이터 구조입니다.
  • 유연한 문서 구조
    • Lucene은 문서(Document) 기반 저장 방식을 사용하며, 각 문서는 필드(Field)로 구성됨
    • 필드는 여러 유형(String, Integer, Date 등)을 지원
  • 확장 가능성
    • 대량의 데이터를 효율적으로 색인 가능
    • 멀티스레딩 지원, 빠른 검색 속도 유지

1.2 ElasticSearch 활용 사례

  • 로그 및 모니터링 데이터 분석 (ELK Stack)
  • 웹사이트 검색 시스템 (전자상거래, 문서 검색 등)
  • 빅데이터 분석 및 머신러닝 기반 데이터 처리

1.3 ElasticSearch의 주요 기능

  • 강력한 Full-Text 검색 지원
  • 분산 아키텍처를 통한 수평 확장 지원
  • 다양한 쿼리 언어(Query DSL) 및 집계(Aggregation) 기능 제공
  • 실시간 데이터 색인 및 분석 가능

1.4 ElasticSearch 아키텍처


https://devopsideas.com/different-elasticsearch-components-and-what-they-mean-in-5-mins/

  • Cluster
    • 여러 개의 노드로 구성된 ElasticSearch의 전체 시스템
  • Node
    • 클러스터 내에서 데이터를 저장하고 검색 요청을 처리하는 개별 서버
  • Index
    • 인덱스는 문서의 모음
  • 클러스터 내부에서 노드는 다음과 같은 역할을 합니다.
    • Master Node
      • 클러스터 상태 관리 및 노드 추가/제거 수행
    • Data Node
      • 데이터 저장 및 검색, 색인 처리 담당
    • Ingest Node
      • 데이터를 전처리하여 저장하는 역할 수행
    • Coordinator Node
      • 클라이언트 요청을 받아 데이터 노드로 분배
  • Shard와 Replica
    • 샤드 → 데이터를 분할하여 저장하는 기본 단위
    • 레플리카 → 데이터 복제본을 유지하여 고가용성 제공
    • 샤드와 레플리카 개수 조절을 통해 ElasticSearch의 성능 최적화가 가능합니다.

1.5 클러스터 상태

  • 엘라스틱서치에서 클러스터 상태는 세 가지 색상, 즉 green, yellow, red로 표시됩니다.
  • 각 색상은 클러스터의 건강 상태를 나타내며, 다음과 같은 의미를 가집니다.
    • Green (녹색)
      • 클러스터의 모든 주 샤드(primary shards)와 복제 샤드(replica shards)가 정상적으로 할당되어 있습니다.
      • 이 상태는 클러스터가 최적의 상태에 있으며 모든 데이터가 안전하게 복제된 것을 의미합니다.
    • Yellow (노란색)
      • 모든 주 샤드는 할당되었으나 하나 이상의 복제 샤드가 할당되지 않았습니다.
      • 주 샤드는 사용 가능하지만, 일부 복제 샤드가 할당되지 않아 데이터의 내고장성이 완벽하지 않은 상태입니다.
      • 주 샤드의 노드가 실패할 경우, 해당 데이터의 복제본이 없어 데이터 손실의 가능성이 있습니다.
    • Red (적색)
      • 하나 이상의 주 샤드가 할당되지 않은 상태입니다.
      • 데이터의 일부가 사용 불가능함을 의미하며, 시스템에 문제가 있는 상태입니다.
      • 적색 상태에서는 해당 샤드의 데이터에 접근할 수 없으므로 데이터 손실이 발생할 수 있습니다.
  • 클러스터의 상태는 주 샤드와 복제 샤드의 할당 여부에 따라 결정되며, 데이터의 가용성과 안정성을 직접적으로 반영합니다.

1.6 공식 문서


2. ElasticSearch 구축

2.1 Docker-Compose 파일 작성

  • docker-compose.yml
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.5.0
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ports:
      - "9200:9200"
    volumes:
      - esdata:/usr/share/elasticsearch/data
  kibana:
    image: docker.elastic.co/kibana/kibana:8.5.0
    container_name: kibana
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch
volumes:
  esdata:
    driver: local

2.2 ElasticSearch 및 Kibana 실행

docker-compose up -d

2.3 ElasticSearch 상태 확인

curl -X GET "http://localhost:9200/_cluster/health?pretty"

3. 데이터 인덱싱 및 검색 실습

3.1 샘플 데이터 인덱스 생성

curl -X PUT "http://localhost:9200/sample_index" -H 'Content-Type: application/json' -d'
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1
  },
  "mappings": {
    "properties": {
      "name": { "type": "text" },
      "age": { "type": "integer" },
      "city": { "type": "keyword" }
    }
  }
}'

3.2 데이터 삽입

curl -X POST "http://localhost:9200/sample_index/_doc/1" -H 'Content-Type: application/json' -d'
{
  "name": "Sam Doe",
  "age": 40,
  "city": "Seoul"
}'

3.3 데이터 검색 (Query DSL 활용)

curl -X GET "http://localhost:9200/sample_index/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match": {
      "name": "John"
    }
  }
}'

profile
기록하고 소화해보자! 소화가 안되거나 까먹으면 다시 꺼내서 보자! 오늘의 나는 어제의 나보다 강하다!

0개의 댓글