LLM

OpenSearch 란 ? - AWS의 ElasticSearch, 신흥 Vector 검색의 강자가 될 것인가

aiden0729

 

 

Elasticsearch와 Kibana의 대시보드는 오픈소스 라이선스였지만, AWS가 해당 오픈소스를 상업화하면서 Elastic은 2021년 License를 기반으로 상업적 제약을 걸었고, 이 때문에 AWS는 Elasticsearch를 fork한 서비스를 만들었는데 해당 서비스가 Opensearch 이다.

 

Opensearch는 Elasticsearch의 역색인 구조를 그대로 이식하였으며, ML이나 보안 분야에서도 추가적인 서비스를  제공한다고 밝혔으며, 이러한 방식은 Apache Lucene의 역색인을 wrap-up 및 구조화 할 수 있었기 때문에 가능한 것으로 생각된다.

Lucene은 2024년 10월 10.0 이상의 버전을 발표하기 시작하였는데 해당 버전에서는 SIMD ( Single Instruction, Multiple Data ), Prefetch 등을 통해 CPU의 병렬성과 병목현상을 개선하였다고 발표하였으며, 이는 9.x 버전에서 지원하던 Vector 검색에 더 최적화 하기 위한 업데이트라고 생각할 수 있다.

Opensearch에서는 2025년 5월에 해당 Lucene 10.0 이상 버전을 팔로우업하면서 Opensearch 3.0 버전을 발표하였다. Opensearch는 이를 통해 VectorSearch의 검색성능이 향상되었으며, Kafka 등과의 연동성도 향상되었다고 발표하였으며, 또한 GPU 최적화와 hybrid 검색에서 z-score 정규화를 통해 검색 성능을 높힌 것으로 생각된다. 또한 Agent 친화적인 MCP 프로토콜 등도 제공하면서 기존의 전통적인 검색 툴을 기반으로한 VectorDB와 엔진에 특화된 방향성을 제시한다고 보여진다.

링크 : https://docs.opensearch.org/docs/latest/version-history/

 

Version history

Version history

docs.opensearch.org

 

 

 

1) 구성 

기본적인 단어 및 항목은 아래와 같은데, 특징적인 것은 shard의 개념이다. 검색 엔진은 실시간성이 중요하며, 따라서 병렬+분산이 굉장히 중요하다고 할 수 있는만큼 shard를 각 서버에 분산 시켜서 실제 검색할 때는 병렬적으로 검색 결과를 나올 수 있게 한다. 이는 클러스터와 하위노드에 의해 작동되고 관리된다. 

항목 설명
Document JSON 포맷으로 저장되는 단일 데이터 단위. DB의 "행(row)"과 유사
Index 여러 Document의 집합. DB의 "테이블(table)"과 유사
Cluster / Node 여러 노드(서버)로 구성된 실행 환경. 하나의 클러스터가 여러 노드로 구성됨
Shard Index를 분할한 조각. 데이터를 노드에 균등하게 분산하여 저장
Primary / Replica Primary는 원본 샤드, Replica는 복제본. 장애 대비 + 검색 부하 분산
Inverted Index 단어 ➝ 문서 목록 구조. 빠른 텍스트 검색을 위한 핵심 구조
Relevance (BM25) 문서의 중요도를 계산해 정렬. 단어 빈도, 희귀성, 문서 길이 반영
Translog 변경 사항을 임시 저장하는 로그. 디스크에 flush되기 전까지 데이터를 유지
Refresh 인메모리 데이터를 검색 가능하도록 만드는 동작 (비영속)
Flush 데이터를 디스크에 영구 저장 (fsync 수행)
Merge Lucene 세그먼트를 통합해 검색 성능 및 저장 효율 최적화

 

 

 

 

2) 기본 검색 및 통신 방법 ( bm25 기반 full-text search )

RestAPI의 통신 방식을 기본적으로 지원한다. Dynamic Mapping을 통해 인풋되는 문서의 타입을 추론할 수 있다. 검색은 Query DSL ( Domain Specific language ) 로 JSON 기반 쿼리 언어로 구성되는데 'match_all', 'match', 'term', 'range', 'bool' 등을 지원한다. 

- match all : 인덱스 전체 검색

- match : 해당 조건이 포함된 문서 검색 ( text(분석) 필드 전용, 소문자 처리 )

- term : 해당 조건의 정확한 문서 검색 ( keyword(매칭) 필드 전용, 띄어쓰기 및 대소문자 일치 필요 )

- range : 숫자의 범위 설정 검색

- bool : 위의 여러 조건을 결합 검색 ( must = AND, should = OR

 

 

검색 결과는 아래와 같은 정보를 포함한다. 

필드 설명
took 쿼리 수행 시간 (ms)
timed_out 타임아웃 여부
_shards 샤드별 성공/실패 개수
hits.total 검색 결과
hits.hits 결과 문서 목록 (_id, _score, _source 포함)
_score 관련도 점수 (BM25 기준)

 

 

참고 : bm25 관련 포스팅

https://aiden0729.tistory.com/26

 

bm25란 ? - TF IDF의 진화형

TF-IDF란 ? TF-IDF ( Term Frequency-Inverse Document Frequency )LLM의 등장으로 텍스트 관련 클래시컬한 알고리즘은 많이 쓰이지 않는 추세이지만 여전히 Data Science 나 대용량의 text 데이터를 처리 할 때, 혹은

aiden0729.tistory.com

 

 

 

 

 

 

 

3) 확장 검색 및 통신 방법 ( Semantic, Hybrid 등 )

 

기본 Search를 넘어 LLM 시대에 맞춘 다양한 Search도 제공하고 있는데, 대표적으로는 아래와 같다.

 

 

1. Semantic Search

bm25는 이미 강력한 검색 도구이지만, 예를들어 'puppy'를 검색했을 때 'dog'를 찾아오는 의미기반 탐색은 하지 못한다.

이로 인해 'semantic' 의 뜻과 같이 형태보다는 '의미론적인' 탐색을 할 때 사용되며, 사실 2000년대 인터넷이 나올 때부터 온톨로지 등과 같이 등장했던 상당히 포괄적인 개념이다.

 

다만 Opensearch에서 정의하는 Semantic Search  는 '텍스트 벡터변환 -> 벡터 인덱스 저장 -> 벡터 검색' 의 일련의 과정이라고 할 수 있다.  

 

 

텍스트 벡터변환 

PUT /_ingest/pipeline/nlp-ingest-pipeline
{
  "description": "A text embedding pipeline",
  "processors": [
    {
      "text_embedding": {
        "model_id": "bQ1J8ooBpBj3wT4HVUsb",
        "field_map": {
          "passage_text": "passage_embedding"
        }
      }
    }
  ]
}

 

벡터인덱스 (knn임베딩 예시 코드)

-> 기본적으로 lucene 이지만 다중 엔진 지원으로 Faiss와 같은 엔진도 사용 가능

PUT /my-nlp-index
{
  "settings": {
    "index.knn": true,
    "default_pipeline": "nlp-ingest-pipeline"
  },
  "mappings": {
    "properties": {
      "id": { "type": "text" },
      "passage_embedding": {
        "type": "knn_vector",
        "dimension": 768,
        "method": {
          "engine": "lucene",
          "space_type": "l2",
          "name": "hnsw"
        }
      },
      "passage_text": { "type": "text" }
    }
  }
}

 

 

벡터검색 ( neural 쿼리 방식 )

GET /my-nlp-index/_search
{
  "query": {
    "neural": {
      "passage_embedding": {
        "query_text": "Hi world",
        "model_id": "bQ1J8ooBpBj3wT4HVUsb",
        "k": 100
      }
    }
  }
}

 

 

 

기본적으로는 벡터검색의 기본인 최근접 이웃을 지원한다. 아래의 kNN 및 aNN 포스트와 같이 기본적으로는 aNN의 method를 사용하여 근사 이웃을 찾는 방법을 사용한다.

 

kNN : https://aiden0729.tistory.com/24

 

kNN이란 ? ( k-Nearest Neighbors )

kNN은 Classical한 ML에서도 자주 사용되지만, LLM분야에서는 RAG에서 언급되는 VectorSearch의 시작같은 개념이다. kNN 개념은 최근접 이웃이라는 이름과 같이 직관적이다. 가장 가까운 k개의 벡터를 찾는

aiden0729.tistory.com

 

aNN : https://aiden0729.tistory.com/25

 

aNN(Approximate Nearest Neighbor)

kNN이란 ? kNN이란 ? ( k-Nearest Neighbors )kNN은 Classical한 ML에서도 자주 사용되지만, LLM분야에서는 RAG에서 언급되는 VectorSearch의 시작같은 개념이다. kNN 개념은 최근접 이웃이라는 이름과 같이 직관적

aiden0729.tistory.com

 

 

 

 

 

 

2. Hybrid Search

 

Hybrid는 위에서 언급한 bm25와 vector 검색을 합친 방법이다. serach engine 부분 등만 바꿔주면 실행할 수 있다. 

GraphDB(neo4j 등) 과 같은 Lucene을 사용하는 곳에서는 Graph 탐색까지 더해 3중 hybrid를 지원하는 곳도 있다.

GET /my-nlp-index/_search?search_pipeline=nlp-search-pipeline
{
  "_source": { "exclude": ["passage_embedding"] },
  "query": {
    "hybrid": {
      "queries": [
        { "match": { "passage_text": { "query": "Hi world" } } },
        {
          "neural": {
            "passage_embedding": {
              "query_text": "Hi world",
              "model_id": "bQ1J8ooBpBj3wT4HVUsb",
              "k": 5
            }
          }
        }
      ]
    }
  }
}