跳到主要内容

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 其他方案

特性MilvusPineconeQdrantWeaviate
开源❌(SaaS)
分布式
数据规模十亿级十亿级千万级千万级
标量过滤
混合搜索
部署方式自建/云仅云自建/云自建/云

常见面试问题

Q1: Milvus 和 Elasticsearch 做向量搜索有什么区别?

答案

对比MilvusElasticsearch (8.x+)
定位专用向量数据库全文搜索引擎(附带向量功能)
向量索引HNSW、IVF、PQ 等HNSW
性能向量搜索性能极优向量搜索性能一般
全文搜索不支持核心功能
标量过滤支持强大
适合场景向量为主的检索全文+向量混合搜索

如果向量搜索是核心需求(如 RAG),优先选 Milvus。如果需要全文搜索 + 向量结合,Elasticsearch 更方便。

Q2: Milvus 如何实现高可用?

答案

  1. Proxy 无状态:可水平扩展,通过 LB 分发请求
  2. DataNode/QueryNode:多副本部署,一个节点故障由其他节点接管
  3. Etcd 集群:元数据高可用
  4. 对象存储:MinIO/S3 本身具备高可用
  5. 日志系统:Pulsar/Kafka 集群保障 WAL 不丢失

Q3: Milvus 的 Segment 和 Compaction 机制?

答案

  • Segment:数据写入时先进入 Growing Segment(内存),达到 512MB 后变为 Sealed Segment(持久化到 S3)
  • Compaction:定期将小 Segment 合并成大 Segment,类似 LSM-Tree 的 Compaction
    • 减少 Segment 数量,提升查询性能
    • 合并小文件,减少 I/O

相关链接