数据处理
本文详细介绍了 Milvus 中数据插入、索引建立和数据查询的实现。
数据插入
在 Milvus 中,你可以选择一个 Collection 使用多少个分片--每个分片映射到一个虚拟通道*(vchannel*)。如下图所示,Milvus 会将每个vchannel分配给一个物理通道*(pchannel*),每个pchannel绑定到一个特定的 Streaming Node。

数据验证后,Proxy 会根据指定的分片路由规则将写入的信息拆分成不同的数据包分片。

然后将一个分片*(vchannel*)的写入数据发送到pchannel 对应的 Streaming Node。

Streaming Node 为每个数据包分配一个 TSO(时间戳分配服务),以建立总的操作排序。在将有效负载写入底层 WAL(Write-Ahead Log) 之前,它会对有效负载执行一致性检查。一旦数据持久地提交到 WAL,就能保证不会丢失--即使发生崩溃,Streaming Node 也能重放 WAL 以完全恢复所有待处理操作。
与此同时,Streaming Node 还能异步地将已提交的 WAL 条目切分成不连续的段。有两种分段类型:
- Growing Segment:任何尚未预存到 Object Storage 中的数据。
- Sealed Segment:所有数据都已持久化到 Object Storage 中,Sealed Segment 的数据是不可变的。
从 Growing Segment 过渡到 Sealed Segment 的过程称为 Flush。一旦 Streaming Node 摄取并写入了该分段的所有可用 WAL 条目,即底层 WAL(Write-Ahead Log) 中没有更多待处理记录时,Streaming Node 就会触发 Flush,此时该分段就会最终确定并优化读取。
建立索引
索引建立由 DataNode 执行。为了避免频繁为数据更新建立索引,Milvus 将 Collection 进一步划分为多个分段,每个分段都有自己的索引。

Milvus 支持为向量字段、标量字段和主键字段创建索引。索引构建的输入与输出均存放在 Object Storage 中:DataNode 从 Object Storage 中的 Segment 加载待索引的 Binlog Snapshot,在内存中反序列化数据与元数据并构建索引;构建完成后,再将索引序列化并写回 Object Storage。
索引构建主要涉及向量和矩阵操作,因此是计算和内存密集型操作。向量因其高维特性,无法用传统的树形索引高效地建立索引,但可以用这方面比较成熟的技术建立索引,如基于集群或图形的索引。无论其类型如何,建立索引都涉及大规模向量的大量迭代计算,如 Kmeans 或图遍历。
与标量索引不同,构建向量索引需要充分利用 SIMD(Single Instruction, Multiple Data)加速。Milvus 原生支持 SSE、AVX2 和 AVX512 等 SIMD 指令集。向量索引构建通常具有阶段性突发和高资源消耗的特点,因此弹性伸缩对控制总体成本非常重要。后续版本还会继续探索异构计算和 Serverless 计算,以进一步降低索引构建成本。
此外,Milvus 还支持标量过滤和主键字段查询。为了提高查询效率,Milvus 还内置了布隆过滤索引、哈希索引、树型索引和倒排索引等索引,并计划引入更多外部索引,如位图索引和粗糙索引。
数据查询
数据查询指的是在指定的 Collection 中搜索与目标向量最接近的k个向量,或搜索与向量在指定距离范围内的所有向量的过程。向量会连同其相应的主键和字段一起返回。

Milvus 中的 Collection 分成多个分段;Streaming Node 加载 Growing Segment 并维护实时数据,而 QueryNode 则加载 Sealed Segment。
当收到查询/搜索请求时,Proxy 会将请求广播给负责相关分片的所有 Streaming Node,以进行并发搜索。
当收到查询请求时,Proxy 会同时请求持有相应分片的 Streaming Node 执行搜索。
每个 Streaming Node 生成一个查询计划,搜索其本地不断增长的数据,同时联系远程 QueryNode 检索历史结果,然后将这些结果汇总为一个分片结果。
最后,Proxy 收集所有分片结果,将其合并为最终结果,并返回给客户端。

当 Streaming Node 上的 Growing Segment 被 Flush 为 Sealed Segment 时,或者当 DataNode 完成 Compaction 时,Coordinator 会启动移交操作,将增长数据转换为历史数据。然后,Coordinator 会在所有 QueryNode 上平均分配 Sealed Segment,平衡内存使用率、CPU 开销和分段数,并释放任何冗余分段。
下一步
- 了解如何 使用 Milvus 向量数据库进行实时查询。
- 了解 Milvus 中的数据插入和数据持久性。
- 了解如何 在 Milvus 中处理数据。