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