AI向量数据库选型实战:Milvus与Qdrant embedding检索引擎对比与部署

AI向量数据库是大模型开发和AIGC应用的基础设施,负责存储和检索文本、图像等数据的embedding向量。MilvusQdrant是目前主流的两个开源向量数据库,分别走分布式架构和轻量级单机路线,选型时需要从写入吞吐、检索延迟、分布式扩展和运维成本四个维度做对比。

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/

(0)
小编小编
上一篇 7小时前
下一篇 6小时前

相关推荐