向量数据库(Vector Database)。
传统数据库的局限
传统关系型数据库擅长精确匹配:WHERE name = 'Alice'。但面对以下场景时力不从心:
以图搜图:找出"视觉上相似"的图片
语义搜索:用一句话找出"含义相近"的文档
推荐系统:找出"行为上相似"的用户
这类问题的本质是相似性搜索,而不是精确匹配。
向量与嵌入(Embedding)
AI 模型(如 BERT、CLIP、text-embedding-ada-002)可以将非结构化数据转化为高维浮点数向量,称为 Embedding:
"今天天气真好" → [0.12, -0.87, 0.34, 0.91, ...] # 768 维语义相近的内容,其向量在空间中的距离也更近。相似性搜索就转化为了近似最近邻(ANN, Approximate Nearest Neighbor)搜索问题。
向量数据库的核心能力
原始数据 → Embedding 模型 → 向量 → 向量数据库存储 → ANN 查询 → Top-K 结果| 能力 | 说明 |
|---|---|
| 高效 ANN 搜索 | 亿级向量毫秒级返回 |
| 多种索引支持 | IVF、HNSW、DiskANN 等 |
| 标量过滤 | 向量搜索 + 条件过滤组合查询 |
| 水平扩展 |
| 数据库 | 定位 | 特点 |
|---|---|---|
| Milvus | 云原生分布式 | 功能最全、生产级、支持超大规模 |
| Pinecone | 全托管 SaaS | 开箱即用,不可自托管 |
| Weaviate | 开源 | 内置 vectorizer,GraphQL 接口 |
| Qdrant | 开源 Rust 实现 | 轻量高性能,适合中小规模 |
| pgvector | PostgreSQL 插件 | 现有 PG 用户的低成本选择 |
| Chroma | 开源 | 开发调试友好,不适合生产 |
二、Milvus 深度介绍
2.1 项目背景
Milvus 由 Zilliz 于 2019 年开源,是目前 GitHub Star 最多的向量数据库项目(35k+)。2021 年捐赠给 LF AI & Data Foundation,已成为 AI 基础设施领域的事实标准之一。
语言:Go(核心)+ C++(索引库 Knowhere)
2.2 架构设计
Milvus 2.6 在 2.x 存算分离云原生架构基础上引入重要变更:将原先独立部署的三个协调节点 (RootCoord、QueryCoord、DataCoord)合并为单一组件 MixCoord,大幅降低了组件间 RPC 通信开销,简化了运维复杂度,同时保留了各协调器的内部逻辑边界。
┌─────────────────────────────────────────────┐
│ 客户端 │
│ SDK (Python/Go/Java/Node.js) │
└──────────────────┬──────────────────────────┘
│ gRPC
┌──────────────────▼──────────────────────────┐
│ Proxy │
│ 负载均衡 · 鉴权 · 路由 │
└──────────────────┬──────────────────────────┘
│
┌──────────────────▼──────────────────────────┐
│ MixCoord │ ← 2.6 新增:统一协调层
│ ┌────────────┬──────────────┬────────────┐ │
│ │ RootCoord │ QueryCoord │ DataCoord │ │
│ │ 元数据管理 │ 查询任务调度 │ 写入调度 │ │
│ └────────────┴──────────────┴────────────┘ │
└──────────┬───────────────────┬───────────────┘
│ │
┌──────────▼──────┐ ┌────────▼────────┐
│ QueryNode │ │ DataNode │ ← 执行层(仍独立水平扩展)
│ (向量搜索执行) │ │ (数据写入执行) │
└─────────────────┘ └─────────────────┘
↕ ↕
┌─────────────────────────────────────────────┐
│ 元数据存储(etcd) │
├─────────────────────────────────────────────┤
│ 对象存储(MinIO / S3) │
├─────────────────────────────────────────────┤
│ 消息队列(Pulsar / Kafka / Woodpecker)│
└─────────────────────────────────────────────┘
Milvus 2.6 新变化:引入自研 WAL 组件 Woodpecker,可替代 Pulsar/Kafka 作为轻量级消息队列,进一步减少外部依赖,降低部署复杂度。
各组件职责:
| 组件 | 职责 | 2.6 变化 |
|---|---|---|
| Proxy | 请求入口,鉴权、路由、负载均衡 | 无变化 |
| MixCoord | 统一协调层,内含 RootCoord / QueryCoord / DataCoord | 新增,替代原三个独立 Coord |
| ↳ RootCoord | 元数据管理(集合、分区、Schema) | 合并入 MixCoord |
| ↳ QueryCoord | 查询任务调度,Segment 负载均衡 | 合并入 MixCoord |
| ↳ DataCoord | 写入任务调度,Segment 分配与 compaction | 合并入 MixCoord |
| QueryNode | 实际执行向量搜索(可水平扩展) | 无变化 |
| DataNode | 实际执行数据写入(可水平扩展) | 无变化 |
| etcd | 存储集群元数据(轻量级 KV) | 无变化 |
| MinIO / S3 | 持久化存储索引文件和原始数据 | 无变化 |
| Woodpecker | 自研轻量 WAL,可替代 Pulsar/Kafka | 2.6 新增 |
MixCoord 合并带来的收益:
三个 Coord 之间的 RPC 调用变为进程内函数调用,延迟降低、吞吐提升
减少需要独立运维的 Pod 数量,部署更简单
元数据一致性更易保证,减少分布式事务复杂度
执行层(QueryNode / DataNode)仍可独立水平扩展,弹性能力不受影响
2.3 核心概念
Collection(集合)≈ 关系型数据库的 Table
└── Schema(字段定义)
├── primary_key(必须)
├── vector field(向量字段,必须)
└── scalar fields(标量字段,可选)
└── Partition(分区,逻辑隔离)
└── Segment(物理存储单元)
├── Growing Segment(写入中)
└── Sealed Segment(已封存,可建索引)
2.4 索引类型选择
向量索引是 Milvus 性能的核心,按场景选择:
| 索引类型 | 原理 | 适用场景 | 召回率 |
|---|---|---|---|
| FLAT | 暴力穷举 | 小数据量(<100万),精确召回 | 100% |
| IVF_FLAT | 倒排量化 | 中等规模,内存充足 | 高 |
| IVF_SQ8 | 量化压缩 | 内存受限场景 | 中 |
| HNSW | 图索引 | 高 QPS,低延迟 | 很高 |
| DISKANN | 磁盘索引 | 超大规模(百亿级),内存受限 | 高 |
| IVF_PQ | 乘积量化 | 极大规模,极低内存 | 中 |
经验法则:
开发测试 →
FLAT生产环境,QPS 优先 →
HNSW生产环境,内存敏感 →
IVF_SQ8或DISKANN
2.5 距离度量方式
| 度量方式 | 特点 | 适用场景 |
|---|---|---|
L2(欧氏距离) | 值越小越相似 | 图像、通用场景 |
IP(内积) | 值越大越相似 | 需归一化,文本语义搜索 |
COSINE(余弦相似度) | 值越大越相似 | 文本语义搜索(推荐) |
三、快速上手示例
3.1 连接与创建集合
from pymilvus import MilvusClient, DataType
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus"
)
schema = client.create_schema(auto_id=False, 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=1000)
index_params = client.prepare_index_params()
index_params.add_index(
field_name="embedding",
index_type="HNSW",
metric_type="COSINE",
params={"M": 16, "efConstruction": 200}
)
client.create_collection(
collection_name="my_docs",
schema=schema,
index_params=index_params
)3.2 插入数据
import numpy as np
data = [
{
"id": i,
"embedding": np.random.rand(768).tolist(),
"text": f"文档内容 {i}"
}
for i in range(10000)
]
# 批量插入,推荐每批 1000~5000 条
batch_size = 2000
for i in range(0, len(data), batch_size):
client.insert(collection_name="my_docs", data=data[i:i+batch_size])
client.flush(collection_name="my_docs")3.3 向量搜索
query_vector = np.random.rand(768).tolist()
results = client.search(
collection_name="my_docs",
data=[query_vector],
limit=10,
output_fields=["text"],
search_params={"metric_type": "COSINE", "params": {"ef": 100}}
)
for hit in results[0]:
print(f"id={hit['id']}, score={hit['distance']:.4f}, text={hit['entity']['text']}")3.4 混合搜索(向量 + 标量过滤)
results = client.search(
collection_name="my_docs",
data=[query_vector],
filter="category == 'tech'", # 标量过滤
limit=10,
output_fields=["text", "category"]
)四、性能调优要点
4.1 索引参数调优
# HNSW 参数说明
# M: 图的最大连接数,越大召回率越高,内存消耗越多(推荐 8~64)
# efConstruction: 建索引时搜索深度,越大质量越高,建索引越慢(推荐 100~500)
# ef: 查询时搜索深度,越大召回率越高,延迟越大(推荐 > limit)
index_params.add_index(
field_name="embedding",
index_type="HNSW",
metric_type="COSINE",
params={"M": 16, "efConstruction": 200} # 建索引时
)
search_params={"params": {"ef": 64}} # 查询时4.2 资源监控与火焰图
当出现查询延迟高、CPU 飙升等问题时,Milvus 各组件(包括 MixCoord、QueryNode、DataNode) 均在 9091 端口暴露 pprof 接口,可采集火焰图定位热点:
# 对目标组件 pod 做端口转发
kubectl port-forward -n milvus <querynode-pod> 9091:9091
# 采集 30 秒 CPU profile(在问题复现期间执行)
curl -o cpu.prof "http://localhost:9091/debug/pprof/profile?seconds=30"
# 生成交互式火焰图,浏览器访问 http://localhost:8080 → View → Flame Graph
go tool pprof -http=0.0.0.0:8080 cpu.prof # 安装 FlameGraph 工具
git clone https://github.com/brendangregg/FlameGraph /opt/FlameGraph
# 生成 SVG 火焰图
go tool pprof -raw -output=cpu.txt cpu.prof
/opt/FlameGraph/stackcollapse-go.pl cpu.txt | /opt/FlameGraph/flamegraph.pl > cpu.svg其他常用 profile:
curl -o heap.prof "http://localhost:9091/debug/pprof/heap" # 内存
curl -o goroutine.prof "http://localhost:9091/debug/pprof/goroutine" # goroutine 泄漏
curl -o mutex.prof "http://localhost:9091/debug/pprof/mutex" # 锁竞争4.3 常见性能问题排查
| 现象 | 排查方向 |
|---|---|
| 查询 P99 延迟高 | QueryNode CPU profile,检查 ef 参数是否过大 |
| 写入吞吐低 | DataNode profile,检查批量大小和 flush 频率 |
| 内存持续增长 | heap profile,检查 Segment 是否正常 compact |
| goroutine 数量异常 | goroutine dump,排查泄漏 |
| MixCoord 响应慢 | MixCoord CPU profile,检查元数据操作热点 |
五、典型应用场景
RAG(检索增强生成)
用户问题 → Embedding → Milvus 向量搜索 → 相关文档 → LLM 生成答案
以图搜图
上传图片 → CLIP Embedding → Milvus 搜索 → 相似图片列表
推荐系统
用户行为 → 用户向量 → Milvus 搜索 → 相似用户 → 协同过滤推荐
异常检测
实时数据 → Embedding → 与历史数据比较距离 → 距离超阈值则告警
六、总结
向量数据库解决了 AI 时代非结构化数据的相似性搜索难题。Milvus 凭借其云原生分布式架构、 丰富的索引支持和活跃的开源社区,已成为生产级向量数据库的首选方案。
Milvus 2.6 核心变化回顾:
| 特性 | 说明 |
|---|---|
| MixCoord | 三个协调节点合并为一,降低通信开销,简化运维 |
| Woodpecker | 自研轻量 WAL,可替代 Pulsar/Kafka |
| 执行层不变 | QueryNode / DataNode 仍独立水平扩展 |
通用最佳实践:
HNSW 索引适合大多数高 QPS 生产场景
批量写入(1000~5000 条/批)显著提升写入吞吐
pprof + 火焰图是 Go 服务性能调优的标准手段
合理设置
ef参数平衡召回率与查询延迟
参考资料
