3. 向量数据库选型:主流方案对比与实战考量

做多模态检索,选对向量数据库,项目就成功了一半。我见过不少团队,算法模型调得漂漂亮亮,结果上线时数据库扛不住召回压力,整个系统直接崩掉。所以这一章,咱们把市面上主流的四个选手——Milvus、FAISS、Qdrant、Weaviate——拉出来遛遛。

先别急着选,搞清楚它们的定位:

  • Milvus:云原生分布式,适合大规模生产环境
  • FAISS:Meta 出品,纯计算库,适合离线或单机场景
  • Qdrant:Rust 写的,性能强悍,适合对延迟敏感的服务
  • Weaviate:自带图结构,适合知识图谱+向量混合查询

我个人习惯,先看业务场景再选工具。你想想看,如果只是做个原型验证,直接上 Milvus 集群,运维成本就够你喝一壶的。

3.1 四个选手的核心差异

先给一张对比表,方便你快速定位:

特性 Milvus FAISS Qdrant Weaviate
开发语言 Go + C++ C++ Rust Go
部署模式 分布式/单机 嵌入式库 单机/集群 单机/集群
索引类型 IVF、HNSW、DiskANN IVF、HNSW、PQ 等 HNSW HNSW
多模态支持 需自行管理字段 不支持 Payload 过滤 原生多模态
扩展性 ★★★★★ ★★☆☆☆ ★★★★☆ ★★★★☆
社区活跃度 高 高 中 中

关键点:FAISS 不是数据库,它没有持久化、没有分布式、没有 CRUD。很多人把它当数据库用,结果数据一多就崩。记住,FAISS 是计算库,不是存储系统。

3.2 选型考量三要素

选向量数据库,我一般只看三个维度:性能、扩展性、成本。别被花里胡哨的功能带偏了。

3.2.1 性能:召回率与延迟的博弈

性能不是单纯看 QPS。你得关注 召回率@topK 和 P99 延迟。举个例子:

# 假设你有 1000 万条 768 维向量
# Milvus 使用 IVF_SQ8 索引,参数 nlist=4096
# 查询时 nprobe=64,召回率约 95%,P99 延迟 15ms

# Qdrant 使用 HNSW,参数 ef_construct=200
# 查询时 ef=128,召回率约 98%,P99 延迟 8ms

我在项目中遇到过,用 FAISS 做离线检索,召回率能到 99%,但一旦要求实时写入+查询,延迟直接飙到 200ms+。为什么?因为 FAISS 的索引重建是阻塞的。

我的建议:如果业务要求 P99 延迟 < 10ms,优先考虑 Qdrant 或 Weaviate。如果数据量在 1 亿以上,Milvus 的分布式能力更靠谱。

3.2.2 扩展性:从单机到集群的平滑过渡

扩展性分两种:垂直扩展(加内存/加 GPU)和水平扩展(加节点)。

  • Milvus:原生支持分片和副本,扩缩容基本无感。我有个项目从 3 节点扩到 10 节点,数据重分布只花了 20 分钟。
  • Qdrant:Raft 协议保证一致性,但扩缩容需要手动触发分片迁移。嗯,这里要注意,迁移期间写入性能会下降。
  • Weaviate:自动分片,但节点数超过 10 个后,协调开销明显增加。
  • FAISS:没有分布式能力。想扩展?自己写 sharding 逻辑。

避坑指南:我曾经在一个项目里用 FAISS 做在线检索,数据量从 500 万涨到 2000 万,单机内存撑爆了。最后不得不连夜迁移到 Milvus,那叫一个痛苦。所以,如果预估数据会快速增长,一开始就别选 FAISS。

3.2.3 成本:不只是服务器费用

成本包括:硬件成本、运维成本、学习成本。

成本类型 Milvus FAISS Qdrant Weaviate
硬件(1 亿向量) 8 核 32G × 3 节点 16 核 128G × 1 节点 8 核 32G × 2 节点 8 核 32G × 2 节点
运维复杂度 高(需 K8s) 低(嵌入代码) 中(Docker 即可) 中(Docker 即可)
学习曲线 陡峭 平缓 中等 中等

说白了,Milvus 功能最强,但运维成本也最高。如果你团队没有专门的运维,我建议从 Qdrant 或 Weaviate 起步。

3.3 多模态场景下的特殊考量

咱们做的是多模态检索,不是单纯的向量检索。这里有几个坑:

  1. 元数据过滤:多模态数据通常附带大量元数据(时间、地点、标签等)。Qdrant 的 Payload 过滤和 Weaviate 的 GraphQL 查询在这方面做得很好。
  2. 混合检索:既要向量相似度,又要关键词匹配。Weaviate 原生支持 BM25 + 向量混合,Milvus 需要配合 Elasticsearch。
  3. 多向量字段:一张图片可能有多个特征向量(颜色、纹理、语义)。Milvus 支持多向量字段,但查询时只能选一个。

实战经验:我做过一个电商多模态搜索项目,图片有 3 个向量(CLIP 语义、SIFT 纹理、颜色直方图)。最后选了 Qdrant,因为它的 Payload 可以存多个向量,而且过滤条件写起来很直观。

3.4 知识体系总览

下面这张图帮你理清选型逻辑:

向量数据库选型决策流程 向量数据库选型决策流程 业务需求 离线/原型验证 在线生产环境 FAISS 数据量 < 1亿 数据量 > 1亿 Qdrant Weaviate Milvus 说明: • 离线场景优先选 FAISS,但注意它没有持久化和分布式能力 • 在线场景根据数据量选择:1亿以下 Qdrant/Weaviate,以上 Milvus

3.5 我的最终建议

说了这么多,给你一个可以直接抄的选型方案:

  • 个人项目/原型:FAISS + SQLite 存元数据,够用
  • 中小团队(< 1 亿向量):Qdrant,部署简单,性能强悍
  • 大团队/海量数据:Milvus,虽然运维重,但扩展性无可替代
  • 需要图结构/知识图谱:Weaviate,原生支持

最后一句:别迷信 benchmark。同样的硬件,不同的数据分布,结果可能天差地别。我建议你拿自己的数据,在 3 个候选方案上各跑一遍,用数据说话。