Vector Database 비교 — Pinecone·Weaviate·Qdrant·Milvus와 임베딩·ANN 검색
이 글의 핵심
생성형 AI와 검색·추천 시스템에서 벡터 데이터베이스는 고차원 임베딩을 저장하고 근사 최근접 이웃(ANN) 검색으로 의미적 유사도를 찾는 핵심 인프라입니다. 본문에서는 개념부터 Pinecone, Weaviate, Qdrant, Milvus의 특성·운영·요금·벤치마크 해석, RAG와 추천 설계까지 실무 관점으로 비교합니다.
벡터 데이터베이스(Vector Database)는 텍스트, 이미지, 오디오 등을 임베딩 벡터로 바꿔 저장하고, 쿼리 벡터와 가장 가까운 벡터들을 빠르게 찾기 위한 저장소입니다. 전통적인 B-Tree 인덱스가 값의 일치나 범위 검색에 맞춰져 있다면, 벡터 DB는 고차원 공간에서의 근사 최근접 이웃 검색(ANN, Approximate Nearest Neighbor)에 맞춰져 있습니다.
이 글은 Pinecone, Weaviate, Qdrant, Milvus 네 가지를 중심으로 배포 형태, 검색 알고리즘, 필터와 하이브리드 검색, 요금과 벤치마크를 읽는 법, RAG와 추천 시스템 설계 시 유의점을 다룹니다.
Vector Database란 무엇인가
문제 정의
임베딩 모델은 입력을 고정 길이의 실수 벡터(예: 384, 768, 1536차원)로 바꿉니다. 의미가 비슷한 데이터는 벡터 공간에서 서로 가깝게 놓이도록 학습되어 있습니다. 쿼리와 가장 가까운 k개를 정확히 찾으려면 모든 벡터와 거리를 계산해야 하므로, 벡터 N개와 차원 d에 대해 쿼리마다 O(N·d) 연산이 듭니다. 수백만에서 수십억 개 규모에서는 이 비용을 감당하기 어려워, 실서비스에서는 정확도를 조금 포기하고 탐색 범위를 줄이는 ANN을 씁니다.
관계형 DB·검색 엔진과의 역할 분담
| 구분 | 전형적인 강점 |
|---|---|
| RDB | 트랜잭션, 조인, 스키마 무결성, 정형 메타데이터 |
| 전문 검색(Elasticsearch, OpenSearch 등) | 역인덱스 기반 키워드 검색(BM25), 형태소 분석기 |
| Vector DB | 대규모 임베딩의 ANN 검색, 벡터와 메타데이터 필터 결합 |
실무에서는 벡터 검색, 키워드 검색, 메타데이터 필터를 함께 쓰는 하이브리드 검색이 흔합니다. 제품마다 이를 한 플랫폼에서 모두 제공하는지, 외부 검색 엔진과 조합해야 하는지가 다릅니다. 반대 방향의 선택지도 있습니다. 이미 PostgreSQL을 쓰고 있고 벡터가 수백만 개 수준이라면 pgvector 확장으로 HNSW나 IVF 인덱스를 만들어 같은 DB 안에서 트랜잭션, 조인과 함께 벡터 검색을 하는 편이 운영할 시스템을 하나 줄여 줍니다. Elasticsearch와 OpenSearch도 벡터 필드와 ANN 검색을 지원합니다.
주요 인덱스와 알고리즘
HNSW(Hierarchical Navigable Small World)는 벡터를 여러 층의 그래프로 연결하고, 위층에서 큰 보폭으로 이동하다 아래층으로 내려가며 이웃을 좁혀 가는 방식입니다. 지연 시간이 짧고 재현율이 높아 가장 널리 쓰이지만, 그래프의 간선 정보까지 메모리에 두어야 해서 메모리 사용량이 큽니다. M(노드당 연결 수), ef_construction, ef(검색 시 후보 수) 같은 파라미터로 속도와 재현율을 조정합니다.
IVF(Inverted File Index)는 k-means로 벡터 공간을 nlist개의 클러스터로 나누고, 검색 시 쿼리와 가까운 nprobe개 클러스터만 탐색합니다. 메모리 효율이 좋고 디스크 기반 구성과도 잘 맞지만, 데이터 분포가 바뀌면 클러스터를 다시 학습해야 할 수 있습니다.
PQ(Product Quantization)나 스칼라·이진 양자화는 벡터를 압축해 메모리 사용량을 크게 줄입니다. 압축으로 거리 계산이 부정확해지므로, 압축된 벡터로 후보를 넉넉히 뽑은 뒤 원본 벡터로 다시 거리를 계산(rescoring)하는 방식과 함께 쓰는 경우가 많습니다.
제품마다 이름은 달라도, 인덱스 종류와 파라미터, 하드웨어의 조합이 지연 시간과 재현율을 결정한다는 점은 같습니다.
임베딩과 유사도 검색
임베딩 파이프라인
- 청킹: 문서를 문단이나 문장 단위로 나눕니다. 청크 크기와 겹침(overlap)은 검색 재현율과 LLM에 넣는 토큰 비용에 직접 영향을 줍니다.
- 임베딩 생성: OpenAI, Cohere 같은 API나
sentence-transformers, BGE 같은 오픈소스 모델로 벡터를 만듭니다. - 저장: 벡터와 함께
document_id,source, 접근 권한, 언어처럼 필터에 쓸 메타데이터를 저장합니다. - 검색: 사용자 질의를 문서와 같은 모델로 임베딩한 뒤 top-k ANN 검색을 합니다.
거리·유사도 척도
코사인 유사도는 두 벡터의 방향이 얼마나 비슷한지를 보며, 텍스트 임베딩에서 가장 널리 쓰입니다. 유클리드 거리(L2)는 공간상의 직선거리이고, 내적(inner product)은 방향과 크기를 함께 반영합니다. 벡터를 길이 1로 정규화하면 내적은 코사인 유사도와 같아지고, L2 거리의 순위도 코사인 유사도의 순위와 같아집니다. 그래서 많은 시스템이 정규화한 뒤 계산이 가장 빠른 내적을 씁니다.
모델이 권장하는 거리 척도와 정규화 여부를 인덱스 설정과 맞추지 않으면 검색 품질이 크게 떨어집니다. 임베딩 모델을 바꿀 때는 벡터 공간 자체가 달라지므로, 새 모델의 질의 벡터를 옛 모델의 문서 벡터와 비교하면 점수가 의미를 잃습니다. 모델을 바꾸면 전체 문서를 다시 임베딩해 재색인해야 합니다.
검색 품질을 좌우하는 요소
청크가 너무 크면 관련 없는 내용이 섞여 벡터가 흐려지고, 너무 작으면 문맥이 끊겨 답에 필요한 정보가 여러 청크에 흩어집니다. 권한, 날짜, 카테고리 필터는 필요하지만, ANN으로 뽑은 후보에 필터를 나중에 적용하는 방식(post-filtering)에서는 필터가 후보 대부분을 걸러 내 결과가 k개보다 적게 남을 수 있습니다. 필터를 검색 과정 안에서 함께 적용하는 방식(pre-filtering, filtered HNSW 등)을 지원하는지가 제품 선택 기준이 되는 이유입니다.
재순위(reranking)도 효과가 큽니다. ANN으로 수십에서 수백 개의 후보를 넉넉히 가져온 뒤, 질의와 문서를 함께 입력받는 교차 인코더(cross-encoder)로 다시 정렬하면 RAG 답변의 근거가 더 정확해지는 경우가 많습니다. 대신 후보 수만큼 모델 추론이 추가되어 비용과 지연이 늘어납니다.
Pinecone vs Weaviate vs Qdrant vs Milvus
아래는 일반적인 제품 성격을 기준으로 한 비교이며, 버전과 요금제에 따라 달라질 수 있습니다.
| 항목 | Pinecone | Weaviate | Qdrant | Milvus / Zilliz Cloud |
|---|---|---|---|---|
| 배포 | 매니지드 SaaS | 매니지드 + 셀프호스팅 | 매니지드 + 셀프호스팅 | 매니지드(Zilliz) + 셀프호스팅 |
| 라이선스 | 비공개(상용) | BSD-3-Clause | Apache 2.0 | Apache 2.0 |
| 강점 | 운영 부담이 가장 적음 | 모듈로 임베딩·재순위·하이브리드 통합 | 필터 결합 검색, 단일 바이너리로 간편한 배포 | 대규모 분산, GPU 인덱스, 다양한 인덱스 종류 |
| 주의점 | 벤더 종속, 과금 구조 이해 필요 | 모듈 구성에 따른 운영 복잡도 | 대규모 클러스터 운영 역량 필요 | 셀프호스팅 시 구성 요소가 많음 |
Pinecone
Pinecone은 벡터 검색에 특화된 매니지드 서비스로, 인프라 프로비저닝과 스케일링을 직접 다루고 싶지 않은 팀에 맞습니다. 서버리스 인덱스를 중심으로 상품 형태가 바뀌어 왔고, 네임스페이스로 테넌트를 나누거나 메타데이터 필터, 희소(sparse)와 밀집(dense) 벡터를 함께 쓰는 하이브리드 검색을 지원합니다. 요금은 무료 Starter, 월 최소 사용 금액이 있는 Standard, Enterprise로 나뉘며, 스토리지와 읽기/쓰기 단위, 호스팅 임베딩 추론 등이 함께 과금될 수 있습니다. 비용을 추정할 때는 공식 가격 페이지의 계산기를 참고합니다.
Weaviate
Weaviate는 오픈소스(BSD-3-Clause)이면서 매니지드 클라우드도 제공합니다. 컬렉션 단위로 객체의 속성과 벡터를 함께 정의하고, 모듈을 통해 데이터를 넣을 때 외부 임베딩 모델을 자동으로 호출하거나 재순위, BM25와 벡터를 섞는 하이브리드 검색을 구성할 수 있습니다. 질의 API는 초기에는 GraphQL 중심이었고, 최근 클라이언트는 gRPC 기반 API를 씁니다. 임베딩 생성과 검색을 한 시스템 안에서 처리하고 싶은 조직이 선택하는 경우가 많습니다. 셀프호스팅할 때는 Kubernetes 배포가 일반적이며 백업과 업그레이드 계획이 필요합니다.
Qdrant
Qdrant는 Rust로 작성된 오픈소스 벡터 DB입니다. 벡터와 함께 저장하는 JSON 페이로드에 인덱스를 만들고, HNSW 탐색 중에 필터 조건을 함께 적용하는 방식으로 필터가 강한 검색에서도 결과 품질을 유지하도록 설계되어 있습니다. Docker 컨테이너 하나로 띄울 수 있어 로컬과 스테이징 환경을 맞추기 쉽고, 매니지드 서비스인 Qdrant Cloud에는 소규모 검증용 무료 티어가 있습니다. Qdrant Cloud 요금은 인스턴스 사양과 디스크, 백업에 따라 정해집니다.
Milvus와 Zilliz Cloud
Milvus는 대규모 벡터 워크로드를 겨냥한 오픈소스 프로젝트로, 여러 ANN 인덱스(HNSW, IVF 계열, DiskANN, GPU 인덱스 등), 대량 임포트, 저장 계층과 연산 계층을 분리한 분산 구조가 특징입니다. 상용 서비스인 Zilliz Cloud는 Milvus 기반 매니지드 서비스입니다. 데이터가 매우 크거나 온프레미스 같은 네트워크 제약이 있는 기업에서 자주 검토됩니다. 분산 모드는 메시지 큐, 객체 스토리지, 메타데이터 저장소 같은 의존 구성 요소가 많아, 소규모 서비스라면 단일 노드 모드(Standalone)나 경량 버전(Milvus Lite)으로 시작하거나 다른 제품과 비교해 보는 것이 좋습니다.
성능 벤치마크
공개 벤치마크를 읽는 법
ann-benchmarks 같은 공개 비교는 특정 데이터셋, 하드웨어, 파라미터에서의 상대 성능을 보여 줍니다. 여기서 나온 “A가 B보다 빠르다”는 결론을 그대로 자사 서비스에 적용하기는 위험합니다. 실제 트래픽은 필터 비율, 배치 크기, 동시 요청 수, 캐시 적중률이 실험 조건과 다르고, 임베딩의 차원과 분포가 다르면 인덱스의 최적 파라미터도 달라집니다. 무엇보다 처리량은 재현율(recall@k)을 몇 %로 맞췄는지에 따라 크게 바뀌므로, 재현율을 함께 적지 않은 QPS 숫자는 비교 근거가 되지 못합니다.
내부 벤치마크
자사 데이터로 비교할 때는 실제 서비스와 같은 임베딩 파이프라인으로 샘플과 전체 데이터를 색인하고, QPS와 p95/p99 지연, 재현율을 함께 측정합니다. 재현율의 정답은 같은 데이터에 대해 전수 검색(brute-force)으로 구한 top-k를 기준으로 합니다. 필터를 켠 경우와 끈 경우를 모두 측정해야 필터가 성능과 결과 수에 주는 영향을 알 수 있고, 문서가 계속 추가되고 삭제되는 서비스라면 쓰기가 진행 중일 때의 검색 지연도 확인해야 합니다. 삭제가 많으면 인덱스에 삭제 표시만 남아 있다가 정리(compaction) 시점에 성능이 변하는 제품도 있습니다.
가격 비교
벡터 DB 비용은 저장 용량, 쿼리와 색인 처리량, SLA나 SSO, 프라이빗 네트워크 연결 같은 부가 기능, 그리고 경우에 따라 임베딩이나 재순위 추론 비용까지 합쳐서 봐야 합니다. 아래는 가격 모델의 구조만 정리한 것이며, 금액은 자주 바뀌므로 각 벤더의 최신 페이지를 기준으로 하시기 바랍니다.
| 제품 | 가격 모델 |
|---|---|
| Pinecone | Starter는 무료. Standard와 Enterprise는 월 최소 사용 금액이 있고, 그 위로 스토리지와 읽기/쓰기 단위가 종량제로 붙음. 공식 가격 |
| Weaviate | 오픈소스는 인프라 비용만. 클라우드는 저장한 벡터 규모와 리소스 기반. Weaviate 가격 |
| Qdrant | 클라우드는 인스턴스 사양과 디스크 기반, 무료 티어 있음. Qdrant 가격 |
| Milvus / Zilliz | 오픈소스는 자체 호스팅 비용. Zilliz Cloud는 서버리스와 전용 클러스터 과금. Zilliz 가격 |
총소유비용은 임베딩을 벤더의 관리형 추론으로 만들지, 외부 API나 자체 GPU로 만들지에 따라 크게 달라집니다. 메모리 비용이 부담이라면 양자화나 디스크 기반 인덱스로 RAM 사용량을 줄이는 옵션을, 같은 질의가 반복되는 서비스라면 결과 캐시로 쿼리 처리량을 줄이는 설계를 함께 검토합니다.
실전 사용 사례
RAG(Retrieval-Augmented Generation)
RAG는 LLM이 답변하기 전에 관련 문서를 검색해 컨텍스트로 넣는 패턴입니다. 사용자 질의를 임베딩하고, 벡터 DB에서 권한과 날짜 같은 필터를 걸어 top-k 청크를 검색하고, 필요하면 재순위 모델로 상위 몇 개를 고른 뒤, 출처 정보와 함께 LLM 프롬프트를 구성합니다.
# 개념 예시: 단계만 표현한 의사코드입니다.
def rag_answer(user_query: str) -> str:
q_vector = embed(user_query)
hits = vector_db.search(
vector=q_vector,
top_k=20,
filter={"tenant_id": current_tenant(), "acl": readable_docs()},
)
reranked = rerank(user_query, hits)[:5]
context = build_context(reranked) # 각 청크에 출처 ID를 붙여 인용 가능하게
return llm.generate(system=RAG_SYSTEM, user=user_query, context=context)
운영에서는 세 가지가 자주 문제가 됩니다. 문서를 고친 뒤 재색인이 늦어 옛 내용으로 답하는 문제, LLM이 컨텍스트에 없는 출처를 지어내는 문제(청크마다 출처 ID를 붙이고 그 ID로만 인용하게 하면 검증이 쉬워집니다), 그리고 권한이 없는 문서가 검색 결과에 섞여 답변으로 새어 나가는 문제입니다. 마지막 문제는 검색 단계의 필터로 막아야 하며, LLM 프롬프트에 “권한 없는 내용은 답하지 말라”고 지시하는 것으로는 막을 수 없습니다.
추천 시스템
사용자와 아이템을 같은 벡터 공간에 두면 추천은 가까운 이웃을 찾는 문제가 됩니다. 콘텐츠 기반 추천은 아이템 설명이나 이미지를 임베딩해 “이 상품과 비슷한 상품”을 찾고, 행동 기반 추천은 최근 조회와 구매 이력을 하나의 사용자 벡터로 모으거나 여러 아이템 벡터로 각각 검색한 결과를 합칩니다.
실시간 이벤트가 많다면 새 아이템과 갱신된 사용자 벡터를 계속 반영하는 스트리밍 색인과, 자주 조회되는 결과의 캐시가 함께 필요합니다.
[이벤트 스트림] --> [특징 추출/임베딩] --> [Vector DB upsert]
^
[배치 재학습] -----------|
선택 기준
데이터 규모와 성장 속도가 첫 번째 기준입니다. 수백만 개 수준이라면 pgvector나 단일 노드 Qdrant, Weaviate로도 충분한 경우가 많고, 수십억 개를 바라본다면 Milvus 같은 분산 구조나 매니지드 서비스를 검토합니다. 메타데이터 필터 조건이 복잡하고 자주 쓰인다면 필터와 벡터 검색을 함께 처리하는 방식과 그 성능이 문서화된 제품이 유리합니다.
팀 역량도 중요합니다. 셀프호스팅을 운영할 인력이 있다면 Qdrant, Weaviate, Milvus의 오픈소스 버전으로 비용을 줄일 수 있지만, 운영 인력이 적다면 매니지드 비용을 감수하는 편이 장애 대응 면에서 안전할 수 있습니다. 기업 환경에서는 VPC 피어링이나 프라이빗 링크, 감사 로그, 데이터 저장 지역 요구 같은 컴플라이언스 조건을 미리 대조해야 합니다.
마지막으로 나중에 제품을 바꿀 가능성을 열어 두는 것이 좋습니다. 원본 문서와 청크, 메타데이터를 벡터 DB 밖에도 보관해 두면 임베딩을 다시 만들어 다른 제품으로 옮길 수 있고, 애플리케이션 코드에서 벡터 DB 호출을 얇은 인터페이스 뒤에 두면 교체 범위가 줄어듭니다.