Milvus是分布式向量数据库,如果构建的是图索引,从图的角度来看,它不同节点有联通性吗?换句话说,构图时时按一张整体的图来进行优化构建的吗?
带着这个问题,我与deepwiki进行了一点探讨。
Milvus 的索引文件已经进行了分段处理, 以提供分布式和大规模向量存储与检索的能力. 举个例子, 对于图索引来说, 它已经不是一张图了, 每个segment可能都对应一张图. 那么问题来了:
Milvus 确实需要对每个分段进行检索,但不需要重新计算向量距离。 系统会在每个分段上执行向量搜索, 每个分段返回其局部的 top-k 结果(包含距离和偏移量)。
全局顺序的保证通过以下机制实现:
1. 分段级搜索: 每个已封存段 (sealed segment) 通过 vector_search() 方法独立执行搜索, 返回该分段内的 top-k 结果。搜索结果包含 seg_offsets_ 和 distances_, 距离值已经在索引搜索时计算完成。
2. 结果合并: 系统使用 insert_helper() 函数通过二分查找将多个分段的结果合并到全局结果中。这个函数根据距离值找到正确的插入位置, 维护全局有序性。
3. 排序策略: 根据度量类型(metric type)使用不同的比较策略。对于 L2 距离, 较小的值更好; 对于 IP/COSINE, 较大的值更好。
4. 分段剪枝优化: 在某些场景下, 系统可以通过计算查询向量(query vector)与分段质心的距离来剪枝不必要的分段(类似于ivfflat中的搜索算法, 先找出最近的N个质心, 然后到这些质心对应的桶中进行计算.)。 这样可以减少需要搜索的分段数量, 提高效率。
分段剪枝优化这段, 我的理解是每个segment都有质心? 然后每个segment实际上内部是graph index? 那也就意味着数据写入向量索引之前, 要先进行路由, 进入离它最近的桶里! 类似于分区索引.
这让我不禁想到vexdb或者海量的vastbase v100的向标混合搜索, 只不过vexdb和vastbase是以标量值范围作为“质心”, 然后这个分枝里面再根据记录条数的多少选择ivfflat OR graphIndex.