Milvus向量数据库选型:架构索引与实战验收

RAG 链路里最容易被轻视的环节是向量存储。文档切好了、Embedding 也算完了,最后一步"存哪、怎么查"决定整个系统的检索延迟和召回质量。Milvus 是这一层的主流选择,但教程大多停在"它能存向量"这个层面,部署形态和索引选型的坑很少有人说透。这篇从选型视角补齐。

存储引擎凭什么和关系库不一样

传统数据库优化的是精确匹配和范围扫描,向量库要解决的是另一个问题:在几百万条高维向量里找出与查询向量距离最近的 K 条。这类近似最近邻搜索(ANN)靠 B+ 树是不可能的,必须靠专门的索引结构。Milvus 把这件事做成了完整的产品:本地单机可以跑,扩到分布式集群也是同一套 API。

它和数据模型的关系可以这样理解:Collection 对标表,Schema 对标表结构,Partition 对标分区——但主键之外的字段都服务于"过滤",真正决定性能的是向量字段上挂的索引。

部署形态怎么选

三档部署对应三种规模,选错档的代价是后期迁移:

  • Milvus Lite:pip 装完直接起,数据量百万条以内、单机验证用。注意它嵌入在应用进程里,应用重启数据要靠本地文件持久化,生产别用。
  • Docker Standalone:单节点全组件,中小规模生产的默认选择。资源底线是 8 核 32GB,低于这个数建索引时会 OOM。
  • 分布式集群:查询、数据、索引三类节点分离,十亿级向量才需要。代价是运维复杂度陡增,没有专职运维别碰。

一个常被忽略的点:数据盘要用 SSD。向量检索是随机读密集型,HDD 上的查询延迟会差出一个数量级。

索引选型的真实折中

索引不是越多越好,每种都拿精度换速度:

索引 原理 适用
FLAT 暴力遍历 百万以下、要求 100% 召回
IVF 系列 聚类分桶后桶内搜 数据量中等,可容忍少量漏召回
HNSW 多层跳表式图 查询延迟最敏感的场景,内存开销大
DiskANN 磁盘优先 超大规模、内存放不下的场景

实测验收时盯三个数:召回率(用 FLAT 跑一遍当基准对比)、p95 延迟、建索引耗时。召回率低于 95% 的索引配置没有上线资格,不管它多快——检索层漏掉的相关段落,生成层补不回来。

建库四步与验收命令

Schema 设计有个新手坑:主键类型确定后不能改,auto_id 一旦开启就无法向集合里写入自定义主键。动数量字段之前先想清楚数据会不会换源重灌。

Python 侧的建库骨架:

from pymilvus import MilvusClient

client = MilvusClient(uri="http://localhost:19530")
client.create_collection(
    collection_name="docs",
    dimension=1024,          # 必须与 Embedding 模型输出维度一致
    metric_type="COSINE",
)
client.insert(collection_name="docs", data=[{"id": 1, "vector": vec}])

上线前跑四步验收:

  1. 维度核对:len(vec) == dimension,维度不一致插入不报错但检索全错,最隐蔽。
  2. 召回抽检:拿 20 条已知答案的查询人工核对 Top5,命中 ≥ 19 条才算过。
  3. 过滤检索:带 filter="source == 'wiki'" 这类标量过滤跑一遍,确认过滤条件真的生效。
  4. 压力摸底:并发 50 查询 5 分钟,看 p95 是否在设计值内。

与其他向量库的边界

Chroma 适合原型,数据过千万就该换;pgvector 适合"顺手用现有 Postgres"的场景,规模再往上性能吃紧;Milvus 的位置是专用检索层,代价是独立运维一套系统。先算清数据量和 QPS 再选,为几万条数据上分布式向量库纯属浪费;反过来,拿 Chroma 硬扛生产流量会在某次批量重建索引时崩给你看。

0

评论0

请先
显示验证码
没有账号?注册  忘记密码?