外观
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_chunks、faq_pairs、product_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_bgeMilvus 最佳实践
向量归一化
向量归一化应在 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类索引需定期compact和load。
| 场景 | 推荐索引 | 说明 |
|---|---|---|
| 高精度召回(<1M 向量) | FLAT | 无损,但慢 |
| 中等规模(1M~10M) | IVF_FLAT / IVF_SQ8 | 平衡速度与精度 |
| 大规模(>10M) | HNSW(低延迟)或 IVF_PQ(高压缩) | HNSW 内存高但快;PQ 节省内存但有精度损失 |
| 实时插入 + 查询 | DISKANN(Milvus 2.3+) | 支持磁盘索引,适合超大规模 |
索引参数调优
IVF_FLAT:nlist=100~1000(约为 sqrt(N))HNSW:M=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) - 低延迟场景:减小参数,牺牲部分召回率