ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 벡터 DB 3대장 비교, 나에게 맞는 선택은?
    IT 2026. 3. 23. 22:00

    왜 벡터 DB가 필요한가?

    ChatGPT에게 "지난달에 정리한 Kubernetes 트러블슈팅 노트 보여줘"라고 물어본 적 있으신가요? 당연히 못 찾아줍니다. LLM(대규모 언어 모델)은 여러분의 개인 데이터를 모르니까요.

    이 문제를 해결하는 게 RAG(Retrieval-Augmented Generation, 검색 증강 생성)입니다. 내 문서를 벡터 DB에 넣어두고, 질문하면 관련 문서를 찾아서 LLM에게 함께 전달하는 방식이죠. 여기서 벡터 DB는 텍스트를 숫자 배열(벡터)로 변환해서 저장하고, "의미가 비슷한 것"을 빠르게 찾아주는 전문 데이터베이스입니다.

    그런데 벡터 DB가 워낙 많습니다. 어떤 걸 써야 할까요? 가장 널리 쓰이는 3개 — Milvus, Pinecone, Qdrant — 를 비교해보겠습니다.

    실생활 활용 시나리오

    시나리오 1: IT 지식 관리
    "3개월 전에 정리한 Docker 네트워크 설정 노트가 있는데, 최근에 방식이 바뀌었어. 최신 정보를 우선으로 찾아줘."
    → 같은 주제라도 최근 문서가 더 가치 있는 상황. 시간 기반 필터링이 필요합니다.

    시나리오 2: 생활 정보 + 업무 지식 혼합
    "이번 주 일정에서 AI 관련 미팅만 찾아줘" 또는 "지난달 가계부에서 식비가 가장 많았던 주는?"
    → IT 지식과 전혀 다른 성격의 데이터를 하나의 시스템에서 관리하고 싶은 상황.

    이 두 가지 요구사항을 염두에 두고 비교해봅시다.

    3대장 한눈에 보기

    항목 Milvus Pinecone Qdrant
    한 줄 요약 대규모 분산의 왕 운영 부담 제로 효율과 유연성의 균형
    라이선스 Apache 2.0 (오픈소스) Proprietary (SaaS 전용) Apache 2.0 (오픈소스)
    개발 언어 Go + C++ 비공개 Rust
    Self-host (직접 설치) 가능 불가 가능
    운영 복잡도 높음 (etcd, MinIO 등 의존성) 없음 (완전 매니지드) 낮음 (단일 바이너리)
    검증된 최대 규모 100억+ 벡터 수십억 (비공개) 수억~수십억
    Hybrid Search 내장 내장 내장
    메타데이터 필터링 강력 보통 가장 강력
    벡터 검색 시 GPU 가속 지원 (CAGRA) 비공개 미지원 (CPU 최적화)

    각각의 핵심 강점과 약점

    Milvus — 대규모 분산이 필요하면 이것

    강점: 100억 개 이상의 벡터를 다뤄본 유일한 오픈소스 벡터 DB입니다. 저장소(storage)와 연산(compute)을 분리하는 아키텍처 덕분에 각각 독립적으로 확장할 수 있죠. GPU 인덱스(CAGRA)를 지원해서 인덱스 빌드와 검색 속도를 수십 배 높일 수 있습니다.

    약점: 분산 모드로 배포하려면 etcd(메타데이터 저장), MinIO(오브젝트 스토리지), Pulsar(로그 브로커)까지 함께 띄워야 합니다. 개인이나 소규모 팀이 운영하기엔 부담이 큽니다.

    이런 분에게: 대기업 RAG 시스템, 수십억 규모 데이터, GPU 서버를 보유한 환경

    Pinecone — 인프라 걱정 없이 바로 시작

    강점: API 키 하나 받으면 5분 안에 시작할 수 있습니다. 서버 관리, 스케일링, 백업 전부 Pinecone이 해줍니다. 2024년 서버리스(Serverless) 전환 이후 유휴 시 비용이 거의 없어졌습니다.

    약점: 클라우드에서만 사용 가능하고, 직접 설치(self-host)는 불가능합니다. 인덱스 알고리즘을 선택하거나 튜닝할 수 없고, 데이터를 다른 DB로 옮기기도 어렵습니다. 벤더 종속(vendor lock-in)이 가장 큰 리스크입니다.

    이런 분에게: 스타트업 MVP, 빠른 프로토타이핑, DevOps 인력이 없는 팀

    Qdrant — 효율과 유연성의 균형

    강점: Rust로 작성되어 같은 하드웨어에서 경쟁 대비 적은 리소스를 사용합니다. 단일 바이너리 하나로 바로 실행할 수 있어서 운영 복잡도가 매우 낮습니다. 그리고 메타데이터 필터링이 세 DB 중 가장 강력합니다 (아래에서 자세히 설명).

    약점: 100억 규모의 초대형 프로덕션 사례는 Milvus보다 적고, 분산 모드의 성숙도가 상대적으로 낮습니다.

    이런 분에게: 개인 서버/로컬 환경, 메타데이터 기반 복잡한 검색이 필요한 경우, 비용 효율이 중요한 경우

    흔한 오해: "GPU 인덱스"란 임베딩 GPU가 아니다

    "Qdrant는 GPU를 못 쓴다"는 말을 들으면 "GPU 없이 어떻게 AI를 하지?"라고 생각할 수 있습니다. 여기서 짚어야 할 것이 있습니다.

    diagram

    1단계(임베딩 생성)는 벡터 DB와 무관합니다. 어떤 벡터 DB를 쓰든 임베딩 모델은 GPU로 돌립니다. 여기서 말하는 "GPU 인덱스"는 2~3단계, 즉 벡터 DB 내부에서 인덱스를 빌드하고 검색할 때 GPU를 쓰느냐의 문제입니다.

    Milvus는 CAGRA라는 GPU 인덱스를 지원해서, 수십억 벡터의 인덱스 빌드와 검색을 GPU로 가속합니다. 대규모 환경에서 의미가 있죠.

    Qdrant는 다른 철학을 택했습니다. Rust의 극한 CPU 최적화 + HNSW 알고리즘 + Quantization(양자화 — 벡터를 압축해서 메모리를 줄이는 기법)으로 GPU 없이도 충분히 빠른 검색 성능을 달성합니다. 실제 벤치마크에서 단일 머신 기준으로 경쟁력 있는 latency(응답 지연)를 보여줍니다.

    게다가 GPU 인덱스는 VRAM(GPU 메모리)에 벡터를 올려야 하므로 VRAM 크기에 따라 스케일이 제한됩니다. Qdrant는 on-disk HNSW(디스크 기반 인덱스)를 지원해서 RAM보다 훨씬 큰 데이터셋도 처리할 수 있죠.

    결론: GPU 인덱스가 없다 ≠ 느리다. 설계 철학의 차이이지, 기능의 결함이 아닙니다.

    Hybrid Search란? — "내장" 지원의 의미

    비교표에서 세 DB 모두 Hybrid Search를 "내장"이라고 적었는데, 이게 뭔지 명확히 짚겠습니다.

    Hybrid Search(하이브리드 검색)는 두 가지 검색을 동시에 하는 것입니다:

    • 의미 검색 (Dense Vector): "쿠버네티스 배포 방법" → "K8s deploy strategy" 같은 의미적으로 비슷한 문서도 찾음
    • 키워드 검색 (Sparse Vector): "kubectl apply" 같은 정확한 단어가 들어간 문서를 찾음

    "내장(네이티브)"이란, 벡터 DB 하나만으로 두 가지 검색을 한 번의 쿼리로 처리하고, 결과를 자동으로 합쳐준다는 뜻입니다. 내장이 안 되면 의미 검색은 벡터 DB에서, 키워드 검색은 Elasticsearch 같은 별도 엔진에서 따로 돌린 뒤 애플리케이션 코드에서 직접 결과를 합쳐야 합니다.

    세 DB 모두 2024~2025년에 sparse vector를 정식 지원하면서 하이브리드 검색이 표준 기능이 되었습니다.

    핵심 차별점: 메타데이터 필터링

    벡터 DB를 쓰다 보면 "의미가 비슷한 문서"만 찾는 것으로는 부족합니다. "이번 달에 작성한 AI 관련 문서 중에서 의미가 비슷한 것"처럼 조건을 걸고 싶은 경우가 대부분이죠. 이걸 처리하는 게 메타데이터 필터링입니다.

    왜 Qdrant의 필터링이 가장 강력한가?

    이유 1: 전용 타입 인덱스

    Qdrant는 메타데이터(payload라고 부름)를 "부가 기능"이 아닌 핵심 기능으로 설계했습니다. 필드 타입별로 전용 인덱스를 생성합니다:

    필드 타입 인덱스 종류 활용 예시
    keyword 해시 인덱스 category = "AI"
    integer / float 범위 인덱스 priority > 3
    datetime 시간 범위 전용 created_at > "2026-01-01"
    geo 위치 기반 인덱스 반경 1km 내 장소
    text 풀텍스트 인덱스 본문 키워드 검색

    Milvus도 scalar 인덱스를 지원하지만, datetime 전용 타입이나 geo 인덱스는 Qdrant만의 네이티브 기능입니다. Pinecone은 메타데이터 크기에 제한(벡터당 40KB)이 있습니다.

    이유 2: 중첩 객체(Nested Object) 필터링

    실제 데이터는 단순한 key-value가 아닌 경우가 많습니다:

    // 이런 구조의 메타데이터가 있을 때
    {
      "author": {
        "name": "홍길동",
        "affiliation": { "org": "KAIST", "dept": "AI" }
      },
      "tags": ["RAG", "벡터DB"]
    }
    
    // Qdrant는 중첩된 필드를 직접 필터링 가능
    { "key": "author.affiliation.org", "match": { "value": "KAIST" } }
    

    Milvus나 Pinecone은 이런 중첩 구조를 지원하지 않아서, author_affiliation_org: "KAIST"처럼 평탄화(flattening)해야 합니다. 데이터가 복잡해질수록 이 차이가 커집니다.

    이유 3: HNSW와 필터의 동시 처리

    벡터 검색과 메타데이터 필터를 함께 쓸 때 성능이 중요합니다:

    diagram

    Qdrant는 HNSW 그래프 탐색 과정에서 각 노드가 필터 조건을 만족하는지 실시간으로 체크합니다. 필터를 먼저 적용하는 방식(인덱스 효율 저하)이나 나중에 적용하는 방식(결과 부족)의 문제를 모두 피합니다.

    IT 지식의 시간 감쇠 — 어떻게 다뤄야 하나?

    IT 업계는 시간 팩터가 매우 중요합니다. "LLM fine-tuning 방법"을 검색하면, 2024년 답변과 2026년 답변이 완전히 다를 수 있습니다. 옛날 정보가 최신 정보와 상충하면, 최신 정보가 이겨야 합니다.

    솔직한 현실: 2026년 기준, 세 DB 모두 네이티브 시간 감쇠(Time-decay) 스코어링을 지원하지 않습니다. "오래된 문서일수록 점수를 자동으로 깎아라" 같은 기능은 아직 없는 거죠.

    하지만 해결 방법은 있습니다:

    방법 1: 시간 범위 필터 (가장 간단)

    벡터 검색에 시간 조건을 추가해서, 특정 기간의 문서만 대상으로 유사도 검색을 합니다. 결과는 벡터 유사도 순으로 정렬됩니다.

    // "최근 3개월 내 문서"에서만 질문과 유사한 것 10개를 찾아줘
    {
      "query": [0.12, 0.45, 0.78, ...],  // 질문을 벡터로 변환한 값
      "filter": {
        "must": [{
          "key": "created_at",
          "range": { "gte": "2025-12-21" }
        }]
      },
      "limit": 10
    }

    간단하지만 한계가 있습니다. 3개월이라는 경계가 딱 잘립니다. 3개월 1일 전 문서는 아무리 유사해도 결과에 포함되지 않죠. 또한 기간 내에서는 어제 쓴 문서나 2개월 전 문서나 동일하게 취급됩니다.

    방법 2: 클라이언트 사이드 재정렬 (가장 유연)

    // 검색 결과를 받은 후, 시간 감쇠 가중치 적용
    for result in search_results:
        age_days = (today - result.created_at).days
        decay = exp(-0.01 * age_days)  # 하루당 1%씩 감쇠
        final_score = result.vector_score * decay

    방법 3: Qdrant의 multi-stage retrieval (가장 정교)

    multi-stage retrieval은 SQL의 서브쿼리처럼, 검색을 단계별로 나눠서 실행하는 Qdrant의 질의 방식입니다. Qdrant는 SQL 대신 JSON 형식의 REST API로 요청을 보내는데, 각 필드의 역할은 다음과 같습니다:

    Qdrant 필드 SQL 대응 하는 일
    prefetch 서브쿼리 (FROM 절의 내부 SELECT) 1차로 후보를 넓게 추출하는 단계
    query ORDER BY similarity(...) 벡터 유사도로 최종 순위를 매기는 단계
    filter WHERE 절 메타데이터 조건 (날짜, 카테고리 등)
    limit LIMIT 반환할 결과 개수

    이제 실제 코드를 보겠습니다:

    // Qdrant에 보내는 검색 요청 (HTTP POST)
    // SQL로 치면: SELECT * FROM (서브쿼리로 100개 추출) ORDER BY 유사도 LIMIT 10
    {
      "prefetch": {
        // 1단계: 최근 6개월 문서 중 100개를 먼저 뽑는다 (그물을 넓게 던지기)
        "filter": {
          "must": [{
            "key": "created_at",
            "range": { "gte": "2025-09-21" }
          }]
        },
        "limit": 100
      },
      // 2단계: 1단계에서 뽑은 100개 중 벡터 유사도가 높은 10개를 최종 선택
      "query": [0.12, 0.45, 0.78, ...],  // 질문을 벡터로 변환한 값
      "limit": 10
    }

    비유하자면, 도서관에서 책을 찾을 때 1단계에서 "최근 6개월 내 입고된 책"으로 서가를 좁히고, 2단계에서 그 안에서 내 질문과 가장 관련 있는 책 10권을 고르는 것과 같습니다. 이렇게 단계를 나누면 오래된 문서가 아무리 의미적으로 유사해도 1단계에서 걸러지기 때문에, 시간 감쇠와 비슷한 효과를 DB 내부에서 처리할 수 있습니다.

    Qdrant의 datetime 전용 타입, 필터, multi-stage retrieval을 조합하면, 네이티브 time-decay가 없더라도 가장 유연하게 우회할 수 있습니다.

    IT 지식 + 생활 정보 — 한 DB에서 어떻게?

    IT 트러블슈팅 노트와 가계부, 일정, 가족 메모를 한 시스템에 넣고 싶다면? 도메인이 완전히 다른 데이터를 관리하는 전략이 필요합니다.

    전략 Milvus Pinecone Qdrant
    데이터 분리 단위 Partition Key Namespace Collection + Payload 필터
    도메인별 시간 감쇠 차등 적용 파티션별 로직 분기 네임스페이스별 로직 분기 payload 필터로 도메인 판별 후 감쇠율 차등 적용

    핵심 포인트는, IT 지식과 생활 정보의 시간 감쇠가 달라야 한다는 것입니다:

    • IT 지식: 시간 감쇠 높음. 3개월 전 Docker 설정법보다 최신 정보가 더 가치 있음
    • 생활 정보: 시간 감쇠 낮음 또는 없음. "아이 알러지 목록"이나 "집 계약 조건"은 1년 전 정보도 그대로 유효

    Qdrant에서는 이렇게 처리할 수 있습니다:

    // 검색 결과 후처리
    for result in search_results:
        domain = result.payload["domain"]
        age_days = (today - result.payload["created_at"]).days
    
        if domain == "IT":
            decay = exp(-0.01 * age_days)   # 빠른 감쇠
        elif domain == "life":
            decay = exp(-0.001 * age_days)  # 느린 감쇠
    
        final_score = result.vector_score * decay

    사용 목적별 최종 추천

    상황 추천 이유
    개인 지식 관리 (로컬 서버) Qdrant 단일 바이너리, 낮은 리소스, 강력한 필터
    스타트업 MVP 빠른 출시 Pinecone 인프라 걱정 없이 즉시 시작
    대규모 엔터프라이즈 RAG Milvus 100억 벡터 검증, GPU 인덱스
    IT + 생활 정보 혼합 관리 Qdrant datetime/geo 타입, nested 필터, 도메인별 차등 처리 유연

    나의 선택: Qdrant

    필자는 로컬 AI 서버에서 IT 기술 노트, 업무 메모, 일정, 가족 정보까지 하나의 시스템으로 관리하고 싶었습니다. 이 상황에서 Qdrant를 선택한 이유를 정리하면:

    1. 운영이 간단합니다. Docker 컨테이너 하나면 됩니다. Milvus처럼 etcd, MinIO, Pulsar를 따로 띄울 필요가 없습니다.
    2. 메타데이터 필터링이 압도적입니다. datetime 전용 인덱스, nested object 필터, geo 인덱스까지. "2026년 3월 AI 관련 문서 중 의미가 비슷한 것"을 한 번의 쿼리로 정확하게 찾을 수 있습니다.
    3. 시간 감쇠를 유연하게 구현할 수 있습니다. IT 지식은 빠르게, 생활 정보는 느리게 — 도메인별 차등 감쇠를 payload 필터와 multi-stage retrieval로 자연스럽게 구현합니다.
    4. GPU 없이도 충분합니다. 개인 규모(수백만 벡터 이하)에서 Rust + HNSW + Quantization의 CPU 성능은 충분하고도 남습니다. GPU는 임베딩 생성에 쓰면 됩니다.
    5. 오픈소스(Apache 2.0)입니다. 벤더 종속 없이 데이터를 완전히 소유할 수 있습니다.

    물론 100억 규모의 엔터프라이즈 RAG라면 Milvus가, 인프라 관리가 불가능한 상황이라면 Pinecone이 정답일 수 있습니다. 정답은 하나가 아니라, 자기 상황에 맞는 선택이 정답입니다.


    이 글은 생성형 AI의 도움을 받아 작성되었습니다. 원본 자료를 기반으로 AI가 초안을 생성하고, 작성자가 검토·편집하였습니다.

Designed by Tistory.