AI向量数据库是大模型开发和AIGC应用的基础设施,负责存储和检索文本、图像等数据的embedding向量。Milvus和Qdrant是目前主流的两个开源向量数据库,分别走分布式架构和轻量级单机路线,选型时需要从写入吞吐、检索延迟、分布式扩展和运维成本四个维度做对比。
Milvus与Qdrant架构差异对比
Milvus采用存算分离架构,由Proxy、Query Node、Data Node、Index Node等多个组件组成,依赖etcd做元数据存储、MinIO/S3做对象存储、Pulsar/Kafka做消息队列。这种架构适合大规模集群部署,但组件较多,运维复杂度较高。Qdrant用Rust编写,单二进制部署,内置存储引擎,无需外部依赖,适合中小规模场景快速上线。
写入性能方面,Milvus在分布式模式下可通过增加Data Node线性扩展写入吞吐,单集群可支撑十亿级向量。Qdrant单节点写入吞吐约5-10万QPS,通过分片机制也能扩展,但水平扩展能力不如Milvus原生。检索延迟方面,两者在百万级向量规模下召回延迟均在毫秒级,差异不大;但在亿级规模下,Milvus的分布式检索架构优势明显。
Milvus集群部署配置实战
使用Docker Compose部署Milvus单机版作为开发测试环境:
# docker-compose.yml
version: '3.5'
services:
etcd:
image: quay.io/coreos/etcd:v3.5.5
environment:
- ETCD_AUTO_COMPACTION_MODE=revision
- ETCD_AUTO_COMPACTION_RETENTION=1000
- ETCD_QUOTA_BACKEND_BYTES=4294967296
volumes:
- etcd_data:/etcd
command: etcd -advertise-client-urls=http://etcd:2379 -listen-client-urls=http://0.0.0.0:2379 --data-dir /etcd
minio:
image: minio/minio:RELEASE.2023-03-20T20-16-18Z
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
volumes:
- minio_data:/minio_data
command: minio server /minio_data
milvus:
image: milvusdb/milvus:v2.4.0
command: ["milvus", "run", "standalone"]
environment:
ETCD_ENDPOINTS: etcd:2379
MINIO_ADDRESS: minio:9000
ports:
- "19530:19530"
- "9091:9091"
depends_on:
- etcd
- minio
volumes:
etcd_data:
minio_data:
使用Python SDK连接Milvus并创建Collection:
from pymilvus import MilvusClient, DataType
client = MilvusClient(uri="http://localhost:19530")
# 创建Collection,定义schema
schema = MilvusClient.create_schema(auto_id=True, enable_dynamic_field=True)
schema.add_field("id", DataType.INT64, is_primary=True)
schema.add_field("embedding", DataType.FLOAT_VECTOR, dim=768)
schema.add_field("text", DataType.VARCHAR, max_length=512)
# 创建索引
index_params = MilvusClient.prepare_index_params()
index_params.add_index(field_name="embedding", index_type="IVF_FLAT", metric_type="COSINE", params={"nlist": 1024})
client.create_collection(
collection_name="docs",
schema=schema,
index_params=index_params
)
# 插入向量数据
data = [
{"embedding": [0.1] * 768, "text": "sample doc 1"},
{"embedding": [0.2] * 768, "text": "sample doc 2"},
]
client.insert(collection_name="docs", data=data)
# 向量检索
results = client.search(
collection_name="docs",
data=[0.15] * 768,
limit=5,
output_fields=["text"]
)
for hits in results:
for hit in hits:
print(f"ID: {hit['id']}, Score: {hit['distance']}, Text: {hit['entity']['text']}")
Qdrant单机部署与API调用
Qdrant部署更为简洁,一条Docker命令即可启动:
docker run -p 6333:6333 -p 6334:6334 \
-v $(pwd)/qdrant_storage:/qdrant/storage \
qdrant/qdrant:v1.8.4
通过REST API创建Collection并写入数据:
import requests, json
BASE = "http://localhost:6333"
# 创建Collection
requests.put(f"{BASE}/collections/docs", json={
"vectors": {"size": 768, "distance": "Cosine"}
})
# 插入向量
requests.put(f"{BASE}/collections/docs/points", json={
"points": [
{"id": 1, "vector": [0.1] * 768, "payload": {"text": "doc 1"}},
{"id": 2, "vector": [0.2] * 768, "payload": {"text": "doc 2"}}
]
})
# 检索
resp = requests.post(f"{BASE}/collections/docs/points/search", json={
"vector": [0.15] * 768,
"limit": 5,
"with_payload": True
})
for point in resp.json()["result"]:
print(f"ID: {point['id']}, Score: {point['score']}, Text: {point['payload']['text']}")
向量索引类型选择与调优
Milvus支持多种索引类型:IVF_FLAT适合百万级数据,精度高但内存占用大;IVF_SQ8通过标量量化压缩向量,内存占用降低75%但精度有损;HNSW图索引检索速度最快,但构建时间长且内存占用高。选型时需要根据数据量级和延迟要求做权衡。
Qdrant内置HNSW索引,无法切换其他索引类型,但提供了量化压缩(Scalar Quantization)功能,可以在精度和内存之间做权衡。对于768维向量,Qdrant开启SQ8量化后内存占用降低约70%,召回率下降约2-3%。
embedding模型对接与数据入库流程
向量数据库的实际使用流程是:先用embedding模型将原始文本编码为向量,再写入数据库。常用embedding模型包括OpenAI text-embedding-3-small、BGE-m3、E5-large-v2等。以BGE-m3为例,通过sentence-transformers库生成embedding:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('BAAI/bge-m3')
embeddings = model.encode(["这是第一段文本", "这是第二段文本"], normalize_embeddings=True)
# embeddings.shape = (2, 1024)
# 写入向量数据库时dim参数设为1024
检索时同样需要用相同模型将query编码为向量,再进行相似度搜索。embedding模型的选择直接影响检索质量,中文场景下BGE系列和E5系列表现较好,英文场景下OpenAI embedding和Cohere embed是主流选择。
选型建议
数据量在千万级以内、追求快速上线和低运维成本,选Qdrant。数据量达到亿级、需要高可用集群和多副本机制,选Milvus。两者都支持过滤检索和混合检索,Milvus的标量字段过滤功能更丰富,Qdrant的payload过滤API更简洁。如果团队没有Kubernetes运维经验,Qdrant的单机模式部署成本更低;如果已有K8s集群,Milvus的Helm Chart部署方案更成熟。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/ai-xiang-liang-shu-ju-ku-xuan-xing-shi-zhan-milvus-yu/