Milvus 向量数据库
问题
Milvus 是什么?它的架构和核心特性是怎样的?
答案
一、Milvus 简介
Milvus 是由 Zilliz 开源的云原生分布式向量数据库,专为十亿级向量相似度搜索设计。它是 CNCF 毕业级项目,也是目前功能最完整的开源向量数据库。
二、架构
核心设计理念:存储计算分离、日志即数据。
| 层级 | 组件 | 职责 |
|---|---|---|
| 接入层 | Proxy | 接收请求、路由分发 |
| 协调层 | RootCoord、DataCoord 等 | 元数据管理、任务调度 |
| 执行层 | DataNode、QueryNode、IndexNode | 数据写入、查询执行、索引构建 |
| 存储层 | Etcd + MinIO + Pulsar | 元数据 + 向量数据 + WAL 日志 |
三、核心概念
Database → Collection → Partition → Segment → Entity
↓
Schema(字段定义)
↓
Fields(id, vector, metadata...)
- Collection:类似关系型数据库的表
- Schema:定义字段类型(向量字段、标量字段)
- Partition:按标量字段分区,加速过滤查询
- Segment:数据存储的最小单元(默认 512MB)
- Index:向量索引(HNSW、IVF_FLAT 等)
四、使用示例
创建 Collection
from pymilvus import MilvusClient
# 连接 Milvus
client = MilvusClient(uri="http://localhost:19530")
# 创建 Collection(自动生成 Schema)
client.create_collection(
collection_name="articles",
dimension=768, # 向量维度
metric_type="COSINE", # 相似度度量
)
手动定义 Schema
from pymilvus import CollectionSchema, FieldSchema, DataType
# 定义字段
fields = [
FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
FieldSchema(name="title", dtype=DataType.VARCHAR, max_length=256),
FieldSchema(name="category", dtype=DataType.VARCHAR, max_length=64),
FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=768),
]
schema = CollectionSchema(fields=fields, description="文章向量库")
# 创建 Collection
client.create_collection(
collection_name="articles",
schema=schema,
)
# 创建 HNSW 索引
index_params = client.prepare_index_params()
index_params.add_index(
field_name="embedding",
index_type="HNSW",
metric_type="COSINE",
params={"M": 16, "efConstruction": 256},
)
client.create_index(collection_name="articles", index_params=index_params)
插入数据
import numpy as np
# 准备数据
data = [
{"title": "深度学习入门", "category": "AI",
"embedding": np.random.rand(768).tolist()},
{"title": "Spring Boot 实战", "category": "Java",
"embedding": np.random.rand(768).tolist()},
]
# 插入
client.insert(collection_name="articles", data=data)
向量搜索
# 基础向量搜索
results = client.search(
collection_name="articles",
data=[query_embedding], # 查询向量
limit=10, # 返回 Top 10
output_fields=["title", "category"], # 返回的标量字段
search_params={"metric_type": "COSINE", "params": {"ef": 64}},
)
# 带标量过滤的搜索
results = client.search(
collection_name="articles",
data=[query_embedding],
limit=10,
filter='category == "AI"', # 先过滤再搜索
output_fields=["title", "category"],
)
五、支持的索引类型
| 索引类型 | 适合场景 | 特点 |
|---|---|---|
| FLAT | 小数据量,要求 100% 精度 | 暴力搜索 |
| IVF_FLAT | 百万级 | 聚类 + 暴力 |
| IVF_PQ | 千万~亿级,内存有限 | 聚类 + 量化压缩 |
| HNSW | 百万~千万,低延迟场景 | 图索引,召回率高 |
| SCANN | 大规模 | Google 开源算法 |
| DiskANN | 超大规模,SSD 存储 | 磁盘索引 |
六、Milvus vs 其他方案
| 特性 | Milvus | Pinecone | Qdrant | Weaviate |
|---|---|---|---|---|
| 开源 | ✅ | ❌(SaaS) | ✅ | ✅ |
| 分布式 | ✅ | ✅ | ✅ | ✅ |
| 数据规模 | 十亿级 | 十亿级 | 千万级 | 千万级 |
| 标量过滤 | ✅ | ✅ | ✅ | ✅ |
| 混合搜索 | ✅ | ✅ | ✅ | ✅ |
| 部署方式 | 自建/云 | 仅云 | 自建/云 | 自建/云 |
常见面试问题
Q1: Milvus 和 Elasticsearch 做向量搜索有什么区别?
答案:
| 对比 | Milvus | Elasticsearch (8.x+) |
|---|---|---|
| 定位 | 专用向量数据库 | 全文搜索引擎(附带向量功能) |
| 向量索引 | HNSW、IVF、PQ 等 | HNSW |
| 性能 | 向量搜索性能极优 | 向量搜索性能一般 |
| 全文搜索 | 不支持 | 核心功能 |
| 标量过滤 | 支持 | 强大 |
| 适合场景 | 向量为主的检索 | 全文+向量混合搜索 |
如果向量搜索是核心需求(如 RAG),优先选 Milvus。如果需要全文搜索 + 向量结合,Elasticsearch 更方便。
Q2: Milvus 如何实现高可用?
答案:
- Proxy 无状态:可水平扩展,通过 LB 分发请求
- DataNode/QueryNode:多副本部署,一个节点故障由其他节点接管
- Etcd 集群:元数据高可用
- 对象存储:MinIO/S3 本身具备高可用
- 日志系统:Pulsar/Kafka 集群保障 WAL 不丢失
Q3: Milvus 的 Segment 和 Compaction 机制?
答案:
- Segment:数据写入时先进入 Growing Segment(内存),达到 512MB 后变为 Sealed Segment(持久化到 S3)
- Compaction:定期将小 Segment 合并成大 Segment,类似 LSM-Tree 的 Compaction
- 减少 Segment 数量,提升查询性能
- 合并小文件,减少 I/O