Skip to content

Milvus 进阶

Milvus 数据库与集合

数据库与集合

在 Milvus 向量数据库中,Database(数据库) 和 Collection(集合) 是两个核心的逻辑组织单元。

概念说明
Database逻辑隔离的命名空间,用于组织多个 Collection。类似于传统关系型数据库中的“数据库”。 • 一个 Milvus 实例可包含多个 Database。 • 不同 Database 中的 Collection 名可以重复。 • 支持用户权限控制(Milvus 2.2+)。
Collection存储向量及其标量字段的数据结构,相当于“表”。 • 定义了 Schema(字段类型、维度、主键等)。 • 可创建索引、插入数据、执行搜索。 • 可进一步划分为 Partition(分区) 以提升查询效率。

数据库使用场景

何时使用 多个 Database:适用于强逻辑隔离或多租户场景:

  • 跨 Database 无法直接 JOIN 或联合查询;管理开销略增。
场景说明
多租户 SaaS 应用每个客户/租户拥有独立 Database,实现数据隔离、权限控制和资源配额管理。
环境隔离dev / staging / prod 环境使用不同 Database,避免互相干扰。
业务域隔离如“金融知识库”、“医疗问答”、“客服对话”等完全独立的业务线,彼此无交叉查询需求。
权限与安全要求高需要为不同团队分配不同 Database 的读写权限(配合 RBAC)。

Database 设计原则

  • 少而精:除非有明确隔离需求,否则优先使用单 Database + 多 Collection。
  • 命名规范:如 rag_prod, tenant_123, research_lab
  • 权限最小化:通过 CREATE USER + GRANT 控制 Database 级访问(Milvus 2.3+ RBAC)

集合使用场景

何时使用 多个 Collection(在同一 Database 内):适用于同一业务域内不同数据类型或用途的场景

  • 同 Database 内 Collection 可统一管理,便于元数据关联或应用层融合检索。
场景说明
不同文档类型pdf_chunksfaq_pairsproduct_descriptions,嵌入模型或分块策略不同。
不同嵌入模型同一批文本用 bge-large 和 e5-mistral 分别生成向量,存入不同 Collection 用于 A/B 测试。
冷热数据分离hot_docs(高频访问) vs archive_docs(低频),可配置不同索引策略。
多模态数据图像向量(dim=512)和文本向量(dim=1024)因维度不同必须分 Collection。

Collection 设计原则

  • Schema 一致性:同一 Collection 内所有实体必须遵循相同字段定义。
  • 避免过度拆分:若多个数据源可共用同一嵌入模型和查询逻辑,应合并到一个 Collection,用 metadata 字段(如 JSON 或 category 字段)区分来源。
  • 利用 Partition(分区)替代 Collection 拆分:
    • 如果只是按时间(如 2024_q1, 2024_q2)或类别(news, blog)划分,且查询常带过滤条件,优先使用 Partition。
    • Partition 共享索引和 Schema,管理更轻量,查询时可指定 partition_names 提升效率。
python
# 创建分区
collection.create_partition("finance")
collection.create_partition("tech")

# 查询时指定分区
collection.search(..., partition_names=["finance"])

典型企业架构示例

shell
Milvus Cluster
├── Database: rag_prod
   ├── Collection: knowledge_base_v1
   ├── Partition: hr_policy
   ├── Partition: it_manual
   └── Partition: finance_guide
   └── Collection: user_embeddings  # 用户行为向量,维度不同

├── Database: tenant_alpha
   └── Collection: private_docs

└── Database: research_dev
    └── Collection: experiment_emb_bge

Milvus 最佳实践

向量归一化

向量归一化应在 Milvus 中处理,而不是在 Xinference 或 Ollama

  • Milvus 官方文档明确指出:使用 COSINE 度量时,无需预先归一化向量,Milvus 会自动处理。
  • Xinference 或 Ollama:仅用于调用 BGE-M3 获取原始 embedding 向量(不做归一化)。

数据预处理与嵌入

文本分块策略

  • 语义分块优于固定长度分块:使用基于句子边界、段落结构或语义连贯性的分块方法(如 LangChain 的 RecursiveCharacterTextSplitter 或 LlamaIndex 的节点解析器)。
  • 保留上下文信息:对相邻块做重叠(overlap),避免关键信息被切断。

嵌入模型选择

  • 使用统一、高质量的嵌入模型,如需多语言支持,选择多语言嵌入模型。
  • 在整个系统生命周期中保持嵌入模型版本一致,避免向量空间漂移。

Milvus 集群架构与部署

部署模式选择

  • 生产环境推荐使用 Milvus 分布式部署(通过 Milvus Operator 或 Helm Chart on Kubernetes)。
  • 组件解耦:Standalone 模式仅适合开发/测试;生产应使用 Cluster 模式(包含 etcd、MinIO/Pulsar/Kafka、多个 QueryNode/DataNode 等)。

资源规划

  • 根据向量规模、QPS、延迟要求估算所需内存、CPU 和存储。
  • 向量维度 × 向量数量 × 4 字节 ≈ 原始向量内存占用(float32)。
  • 索引构建会额外消耗内存(如 IVF_FLAT 约 2x 原始大小)。

Collection 设计与索引优化

Collection Schema 设计

  • 使用 JSON 字段存储元数据(Milvus 2.2+ 支持)。
  • 对高频过滤字段(如 doc_id, category)可单独建标量字段并创建索引(如 inverted index)。
python
from pymilvus import CollectionSchema, FieldSchema, DataType

# 示例字段
id_field = FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True)
text_field = FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=65535)
vector_field = FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=1024)
metadata_field = FieldSchema(name="metadata", dtype=DataType.JSON)  # 存储来源、时间等

schema = CollectionSchema(fields=[id_field, text_field, vector_field, metadata_field])

向量索引选择(关键!)

  • 注意:HNSW 不支持动态删除;IVF 类索引需定期 compactload
场景推荐索引说明
高精度召回(<1M 向量)FLAT无损,但慢
中等规模(1M~10M)IVF_FLAT / IVF_SQ8平衡速度与精度
大规模(>10M)HNSW(低延迟)或 IVF_PQ(高压缩)HNSW 内存高但快;PQ 节省内存但有精度损失
实时插入 + 查询DISKANN(Milvus 2.3+)支持磁盘索引,适合超大规模

索引参数调优

  • IVF_FLATnlist=100~1000(约为 sqrt(N))
  • HNSWM=16, efConstruction=200(构建阶段),查询时 ef=100~500
  • 使用 metric_type="IP"(内积)或 "COSINE"(注意归一化)

查询与检索优化

混合检索(Hybrid Search)

  • 结合向量相似度 + 元数据过滤
  • 利用 RRF(Reciprocal Rank Fusion)或 Weighted Score Fusion 融合多路召回(如关键词 + 向量)。
python
collection.search(
    data=[query_emb],
    anns_field="embedding",
    param={"metric_type": "COSINE", "params": {"nprobe": 10}},
    limit=10,
    expr='category == "finance" and publish_time > 1700000000'  # 标量过滤
)

动态调整 top-k 与 nprobe

  • 高精度场景:增大 nprobe(IVF)或 ef(HNSW)
  • 低延迟场景:减小参数,牺牲部分召回率