Skip to content

Milvus 实现原理

Milvus 是开源向量数据库,专门用于 AI 应用的相似度搜索。理解 Milvus 的实现,需要深入向量检索基础、索引算法、分布式架构和查询处理。

向量检索基础

向量表示

向量是高维空间的点,可以表示任何实体的语义特征。例如,图像通过 CNN 编码成 512 维向量,文本通过 BERT 编码成 768 维向量。语义相似的实体在向量空间中距离更近,这就是向量检索的基础。

向量可以是密集向量(dense vector,每维都有值)或稀疏向量(sparse vector,大部分维是 0)。Milvus 主要处理密集向量。

相似度度量

相似度度量衡量两个向量的相似程度,常见度量有:欧氏距离(L2,越小越相似)、内积(IP,越大越相似)、余弦相似度(Cosine,越大越相似,内积的归一化)、汉明距离(Hamming,用于二值向量)。

欧氏距离适合通用场景,内积适合归一化向量,余弦相似度适合文本。选择合适的相似度度量可以提高检索精度。

暴力搜索(FLAT)

暴力搜索是精确搜索,计算查询向量与所有向量的相似度,返回 TopK。暴力搜索精度最高,但速度慢,时间复杂度 O(n × d),n 是向量数量,d 是向量维度。暴力搜索适合小规模数据或作为基准。

向量索引

IVF(倒排文件)

IVF 将向量聚类成 n 个中心,每个向量分配到最近的中心。搜索时,只搜索最近的 k 个中心(nprobe),减少计算量。IVF 是近似搜索,精度和速度的权衡。IVF 适合中等规模数据。

IVF 的参数:nlist(聚类数量,越大精度越高但越慢)、nprobe(搜索中心数量,越大精度越高但越慢)。nlist 一般取 sqrt(n),nprobe 一般取 8-16。

HNSW(分层可导航小世界图)

HNSW 是基于图的索引,构建多层图,上层稀疏、下层稠密。搜索从最高层开始,贪心查找最近邻,逐层向下,最后一层返回结果。HNSW 是近似搜索,精度和速度的权衡。HNSW 是目前性能最好的索引之一。

HNSW 的参数:M(每个节点的最大连接数,越大精度越高但内存越大)、efConstruction(构建时的候选队列大小,越大精度越高但构建越慢)、ef(搜索时的候选队列大小,越大精度越高但越慢)。M 一般取 16-64,efConstruction 一般取 200-400,ef 一般取 topK。

ANNOY(近似最近邻哦哟)

ANNOY 使用随机投影森林,将高维空间投影到多个低维空间,每个低维空间建立二叉树。搜索时,在多个树中查找最近邻,合并结果。ANNOY 适合静态数据,构建后不支持插入和删除。

DiskANN(磁盘加速索引)

DiskANN 是基于图的索引,专门优化磁盘访问。图的节点存储在磁盘,搜索时尽可能少地读取磁盘节点。DiskANN 适合超大规模数据(数十亿向量),可以存储在单机磁盘。

索引选择

索引选择取决于数据规模、内存大小、精度要求、延迟要求。小数据(< 100 万)用 FLAT 或 IVF,中等数据(100 万 - 1 亿)用 IVF 或 HNSW,大数据(> 1 亿)用 HNSW 或 DiskANN。内存充足用 HNSW,内存受限用 DiskANN。

分布式架构

存算分离

Milvus 采用存算分离架构,包括:接口层(Proxy)、协调层(Root Coordinator、Data Coordinator、Query Coordinator、Index Coordinator)、执行层(Query Node、Data Node、Index Node)、存储层(Meta Store、etcd、MinIO/S3)。

接口层负责客户端连接、SQL 解析、结果聚合。协调层负责任务调度、元数据管理。执行层负责数据写入、索引构建、查询执行。存储层负责元数据持久化、日志存储、对象存储。

数据写入

数据写入流程:客户端发送 Insert 请求给 Proxy,Proxy 转发给 Data Node,Data Node 写入消息日志(MQ),Data Node 写入本地缓存,Data Node 返回成功给 Proxy,Proxy 返回成功给客户端。

Data Node 后台将本地缓存刷盘到 MinIO/S3,生成 Segment。Segment 是不可变的数据文件,包含向量数据、索引、元数据。Segment 可以被加载到内存,供查询。

索引构建

Index Node 监控 Segment,当 Segment 满足索引构建条件时(大小、时间),加载 Segment、构建索引、将索引写回 MinIO/S3。索引构建是异步的,不影响写入和查询。

数据查询

数据查询流程:客户端发送 Search 请求给 Proxy,Proxy 转发给 Query Node,Query Node 从内存或磁盘加载 Segment 索引,执行向量检索,返回结果给 Proxy,Proxy 合并结果、返回 TopK 给客户端。

查询可以指定 consistency_level(一致性级别):Strong(强一致,等待所有 Segment 加载)、Eventual(最终一致,只加载已加载的 Segment)、Bounded(有界一致性,等待指定时间的 Segment)。强一致延迟高,最终一致延迟低。

扩展功能

标量过滤

向量检索经常需要结合标量过滤,例如检索"价格 < 100 的商品"。Milvus 支持标量索引(Bloom Filter、 inverted index)加速标量过滤。查询时,先标量过滤,再向量检索,减少向量检索的计算量。

多向量查询

多向量查询是多个字段的向量联合检索,例如检索"图片和文本都相似的广告"。Milvus 支持多个向量字段,每个字段独立索引,查询时分别检索,然后合并结果。

多租户

Milvus 支持多租户,通过 Partition 隔离不同租户的数据。查询时指定 Partition,只检索该 Partition 的数据,减少索引大小,提高查询速度。

Milvus 是专业的向量数据库,适合图像检索、文本语义检索、推荐系统等场景。理解它的实现,有助于选择索引、配置参数和规划集群架构。