第 7 篇 把查询落到段级执行。段内真正跑 向量索引构建与搜索 的,是 Knowhere——Milvus 文档称之为 core vector execution engine:集成 Faiss、Hnswlib、Annoy 等库,并决定索引构建与搜索在 CPU 还是 GPU 上执行(名字含义:know where to execute)。
本文建立 Knowhere 的 工程接口与类型层次,不重讲 HNSW/DiskANN 的图论与证明(见 db-frontier/08)。读完应能回答:软删如何进到索引查询?IDMAP 为何也算「索引」?新增一种索引要挂在哪一层工厂?
本文是「向量检索引擎」系列第 8 篇(共 18 篇)。→ 系列目录
版本锚定:Milvus 2.6.x Knowhere 文档;算法参数语义外链 frontier/08。
一、Knowhere 在架构中的位置
官方分层(自下而上):
- 系统硬件(CPU/GPU;文档称未来可扩展 DPU/TPU);
- 第三方索引库;
- Knowhere;
- 通过 CGO 与 index / query 相关节点交互(Go 调用 C/C++)。
Architecture Overview 写明 Milvus 构建在 Faiss、HNSW、DiskANN、SCANN 等流行向量检索库之上。Knowhere 的工作是把这些实现收成 统一执行与硬件选择层,而不是让每个 Worker 直接散落调用互不兼容的 API。
与第 7 篇的边界再强调一次:Knowhere 只处理向量索引运算;标量索引、段编排、跨段归并不在 Knowhere 职责内(官方 Knowhere 文档)。
二、相对 Faiss 的明确扩展
官方列出 Knowhere 相对 Faiss 的优势点(A 级文档陈述):
2.1 BitsetView 与软删
Milvus 用 bitset 实现软删:向量仍在库中,但相似度搜索/查询时不参与计算。bitset 中每一位对应一个索引中的向量;标记为删除的向量在搜索中跳过。该参数应用到 Knowhere 暴露的 Faiss 索引查询 API(含 CPU 与 GPU 索引)。
这把「删除」从「立刻改图」变成「查询时掩码」——与 Sealed 不可变、后台 compaction 回收的模型一致(第 3、13 篇)。
2.2 二进制向量上的多种相似度
Knowhere 支持 Hamming、Jaccard、Tanimoto、Superstructure、Substructure 等,覆盖集合相似与化学结构等场景(官方列举)。这超出「只会 L2/IP 的浮点向量」的窄模型。
2.3 AVX512 与自动 SIMD 选择
在 Faiss 已支持的 AArch64、SSE4.2、AVX2 之外,Knowhere 支持 AVX512;文档称相对 AVX2,索引构建与查询可提升约 20%–30%(官方陈述,非本机实测)。
自动 SIMD 选择:把依赖 SIMD
的相似计算抽成多版本(SSE/AVX/AVX2/AVX512),分别编译,运行时按
CPU flag hook 到合适函数指针——用户无需在编译期手动指定
-msse4 一类标志。
2.4 其它优化
文档指向系统论文 Milvus: A Purpose-Built Vector Data Management System(SIGMOD 2021)讨论更多性能优化。论文数字与硬件绑定,引用时须回到原文 figure/table,本篇不转述未核对实验表。
三、代码结构:从 DataObj 到 VecIndex
官方描述的类层次(概念层,便于读源码时找入口):
| 类型 | 角色 |
|---|---|
DataObj |
所有数据结构基类;虚方法 Size() |
Index |
继承 DataObj;Serialize() /
Load() |
VecIndex |
向量索引虚基类;Train()、Query()、统计相关接口 |
FaissBaseIndex /
FaissBaseBinaryIndex |
浮点 / 二进制 Faiss 系索引基类 |
GPUIndex |
Faiss GPU 索引基类 |
OffsetBaseIndex |
自研索引基类;索引文件主要存向量 ID,文档称对 128 维向量文件大小可降约两个数量级 |
3.1 训练与搜索数据同一集合
经典 ANN 流水线常把 训练集 与 检索集 分开(例如 SIFT1M 的 train/test)。Knowhere 文档明确:在 Knowhere 中,训练与搜索使用同一段数据——对 segment 内全部数据 train,再插入并 build。这与「每 Sealed segment 一份索引」(第 3、10 篇)一致:索引生命周期贴着 segment,而不是贴着全局离线训练集。
3.2 IDMAP:暴力搜索也走同一接口
IDMAP
技术上不是索引,而是暴力搜索:插入时无需
train/build,查询直接打在原始向量上。为了代码一致性,它仍继承
VecIndex 并实现相同虚接口。工程含义:
- Flat / 暴力是 召回金标准 与小数据路径;
- 与 HNSW/IVF 共用同一套 Train/Query 调用约定,便于工厂与测试。
3.3 IVF 家族
IVF 派生自 VecIndex 与
FaissBaseIndex,再扩展
IVFSQ、IVFPQ;GPU 侧有
GPUIVF → GPUIVFSQ /
GPUIVFPQ。IVFSQHybrid
为自研混合:粗量化在 GPU、桶内搜索在 CPU,文档称与
GPUIVFSQ 召回相同但减少 CPU–GPU
拷贝。二进制侧有
BinaryIDMAP、BinaryIVF。
算法层的 nlist /
nprobe / PQ 码本含义见 db-frontier/08
与 llm-infra/18;本篇只钉
类型挂载点。
3.4 第三方图/树索引
除 Faiss
外,文档写明当前常见第三方:Annoy(树)、HNSW(图),均派生自
VecIndex。Architecture 还提到 DiskANN、SCANN
等作为 Milvus 整体能力版图——具体版本启用哪些类型以当时
Release Note / Index
文档为准,升级时核对,勿假设全文永久静态。
四、插件契约:如何理解「新增一种索引」
官方给出向 Knowhere 加索引的步骤(工程 checklist):
- 在
IndexEnum增加名称(字符串); - 在
ConfAdapter.cpp增加训练/查询参数校验; - 新文件实现,基类含
VecIndex及必要虚接口; - 在
VecIndexFactory::CreateVecIndex()注册构建逻辑; - 在
unittest下加单测。
量化系参考 IVF_FLAT,图系参考
HNSW,树系参考 Annoy。这就是第 2
篇「ANN 工程接口」要抽象的契约:枚举 → 配置校验 →
VecIndex 实现 → 工厂 → 测试,而不是在 Query Node
里开特例分支。
五、与 Data Node 建索的衔接
Data Processing · Index building:建索由 Data Node 执行;为避免频繁重建,Collection 再分为 segment,每段自有索引。Data Node 从对象存储加载该段日志快照,反序列化后建索,再把索引写回对象存储。向量索引构建是计算与内存密集型,依赖 SIMD;标量侧另有 Bloom、哈希、树、倒排等(官方列举),计划中的 bitmap 等不在本篇展开。
Knowhere 出现在这条路径的 「真正跑 Train/Build/序列化」 处;调度与对象路径是 Data Node + Coordinator(第 10 篇)。
六、学术谱系、争论、开放问题
6.1 谱系
| 层 | 代表 | 本篇角色 |
|---|---|---|
| 算法 | HNSW TPAMI 2018;IVF-PQ;DiskANN NeurIPS 2019 | 外链 frontier/08 |
| 库 | Faiss、Hnswlib、Annoy | Knowhere 之下 |
| 执行引擎 | Knowhere | 硬件选择 + 统一 VecIndex + bitset |
| 系统 | Milvus SIGMOD 2021 → 2.6 Workers | 段生命周期调用 Knowhere |
6.2 争论:库内嵌 vs 独立执行引擎
| 立场 | 主张 |
|---|---|
| 直接链 Faiss | 少一层抽象,调试短 |
| Knowhere 式引擎 | 统一 bitset/SIMD/GPU、多库并存、与软删语义对齐 |
Milvus 选择后者;代价是多一层版本与 CGO 边界。Qdrant 等系统用另一套自研栈达到类似产品目标——对照见第 15 篇,不在此判优劣。
6.3 工程间隙
- 文档中的 AVX512 百分比、IVFSQHybrid「更好性能」均依赖硬件与数据分布;容量规划须自测。
- 「同一 segment 数据既 train 又 search」简化了离线 ANN 竞赛设定,但意味着 segment 重划 / compaction 会触发重建成本。
- GPU 索引在共享集群上的隔离与碎片,官方架构层未给出完备多租户答案(开放问题)。
6.4 开放问题
- DiskANN / 磁盘索引与对象存储冷热分层如何统一计费与缓存(Architecture 提及未来冷热池)?
- 多向量字段时,单段多
VecIndex实例的内存与加载顺序? - 自动 SIMD hook 与发行版 glibc/CPU 基线在容器里的最低能力集如何声明?
七、小结
Knowhere 是 Milvus 的向量索引执行引擎:统一
Faiss/Hnswlib/Annoy 等实现,处理软删 bitset、SIMD/GPU
选择,并用 VecIndex +
工厂形成可扩展插件契约。算法怎么走贪心、怎么量化,去 db-frontier/08;段何时建索、如何
handoff,去第 10 篇;过滤与 bitset 如何夹击召回,去第 11、13
篇。
参考资料
核心论文
- Wang et al., Milvus: A Purpose-Built Vector Data Management System, SIGMOD 2021。
- Malkov & Yashunin, HNSW, IEEE TPAMI 2018(算法外链 frontier/08)。
- Johnson, Douze & Jégou, Faiss 相关工作(库层;具体论文以 Faiss 文档引用为准)。
文档
- Milvus Documentation v2.6.x, Knowhere(分层、相对 Faiss 扩展、类层次、加索引步骤)。
- Milvus Documentation v2.6.x, Data Processing(index building)、Architecture Overview、Bitset。
- db-frontier/08、第 7 篇、系列 index。
返回 系列目录 | 上一篇:Query Node 与 Segcore | 下一篇:分布式 search 归并
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【向量检索引擎】ANN 算法工程接口:从 HNSW/IVF 到 Knowhere 契约
把 HNSW、IVF、DiskANN、Flat 收成引擎侧的索引类型与参数面;说明 Train/Build/Search 生命周期如何贴着 Segment,并与 db-frontier/08 的算法细节、第 8 篇 Knowhere 实现分层分工。
【向量检索引擎】向量引擎全景:算法、RAG 与专用引擎之间的一层
定位专用向量检索引擎相对 ANN 算法、RAG 应用与湖仓格式的分工;以 Milvus 2.6.x 四层架构给出本系列 18 篇地图,并交代从 SIGMOD 2021 系统论文到存算分离演进的谱系。
【向量检索引擎】混合检索与标量过滤:bitset、选择度与引擎落点
在 Milvus 引擎路径上落实 filtered ANN:表达式与 bitset 如何进入 Segcore/Knowhere,pre-filter/post-filter 在段级归并下的失效模式,以及对读 db-frontier/09 的 ACORN 争论而不重写算法全文。
【向量检索引擎】Delete · Upsert · TTL:软删、覆盖写与过期回收
按官方文档说明 delete(主键/过滤)、upsert(override/merge)、collection TTL 的语义;结合 bitset 软删与 compaction 物理回收,划清「搜索不可见」与「对象存储已清理」的时间差。