①架构总览:一条核心设计哲学
数据流自上而下:请求经 Proxy 入系统,协调服务分配任务,Worker 执行,状态最终沉淀到存储层;控制流(元数据、调度)与数据流分离。
②四层组件逐一拆解
接入层(Access Layer)
Proxy(无状态)
系统唯一门面:校验请求、路由、把各 QueryNode 的中间结果做全局归并(reduce/聚合)后返回。前面通常挂 Nginx / K8s Ingress 做负载均衡。
协调服务(Coordinator Service)—— 系统的大脑
RootCoord
处理 DDL/DCL(建/删 Collection、Partition、Index),维护中心授时 TSO,推进时间窗口。
QueryCoord
管理 QueryNode 拓扑与负载均衡,负责把「增长段」交接成「密封段」。
DataCoord
管理 DataNode 拓扑、维护数据元信息,触发 flush / compaction 等后台操作。
IndexCoord
管理 IndexNode 拓扑,下发并跟踪索引构建任务、维护索引元信息。
执行节点(Worker Node)—— 系统的四肢
QueryNode
订阅日志 broker 获取增量(growing segment),从对象存储加载历史段,执行标量+向量混合检索。
DataNode
订阅日志、处理写入/删除,把日志快照打包持久化到对象存储,执行 compaction。
IndexNode
执行索引构建。资源密集,可 serverless 模式按需拉起,不必常驻。
存储层(Storage)—— 系统的骨骼
| 组件 | 职责 | 典型选型 |
|---|---|---|
| 元数据存储 Meta | Schema、节点状态、消费 checkpoint,需强一致 + 高可用 | etcd |
| 消息存储 Log Broker | 持久化流式写入、解耦读写、支持回放(日志即数据) | Pulsar / Kafka(分布式);RocksDB(单机) |
| 对象存储 Object | 日志快照、向量/标量索引文件、中间结果 | MinIO / S3 / GCS |
③数据模型:这些概念必须分清
| Milvus 概念 | 类比关系型库 | 说明 |
|---|---|---|
| Collection | 表(Table) | 一组实体的逻辑集合,含向量字段与标量字段 |
| Entity | 行(Row) | 一条数据 = 若干 field 组成 |
| Field | 列(Column) | 可以是向量,也可以是标量(int/float/string/bool/JSON) |
| Primary Key | 主键 | 唯一标识实体;可自定义,否则自动生成 |
| Partition | 分区 | 物理切分,减少读取范围(按业务维度划分) |
| Sharding | 分片 | 默认 2 个,按主键哈希把写入打散到多节点并行 |
| Segment | 数据文件 | 数据组织与调度的基本单位(见下) |
| Channel (P/V) | 日志主题 | PChannel 物理、VChannel 逻辑,记录增删改日志 |
Segment:数据调度的最小单元
④实现原理:为什么这么设计
日志即数据
所有变更先写日志 broker,再异步快照到对象存储。节点宕机靠「回放日志」恢复增量,读写彻底解耦。
存储计算分离
计算节点无状态、可随 K8s 弹性伸缩;数据在对象存储,扩容不必迁移数据。
Knowhere 引擎
统一的向量执行引擎,封装 FAISS/Annoy/HNSW 与量化算法,屏蔽底层差异,并原生支持 SIMD。
SIMD 加速
距离计算(L2/IP)用 SSE/AVX2/AVX512 单指令多数据并行,是向量检索性能的关键。
谓词下推
混合查询时先把标量过滤(Bitset)应用到各段,再在候选集上做向量检索,大幅减少计算量。
一致性 / Time Travel
RootCoord 的 TSO 提供全局有序时间戳,支持强一致到最终一致多档,以及按时间戳回看历史。
⑤核心流程一:写入(Insert)
- Client 发 Insert,Proxy 校验并写入 Log Broker(WAL,保证持久)。
- DataNode 订阅日志,把数据打包成 日志快照 持久化到对象存储。
- 增量数据以 Growing Segment 形式存在于 QueryNode 内存;达阈值后 DataCoord 将其封口(Seal)。
- IndexCoord 调度 IndexNode 对 Sealed Segment 异步建索引,索引文件写回对象存储。
⑥核心流程二:查询(Search)
查询采用 大规模并行处理(MPP):Proxy 不自己算,而是把请求广播给所有相关 QueryNode,各自算完局部 TopK 再归并。这就是为什么节点越多、检索越快。
⑦核心流程三:建索引(Index Build)
- DataCoord 封口段后,IndexCoord 生成索引任务下发给 IndexNode。
- IndexNode 从对象存储把段数据载入内存(涉及大量 K-means / 图遍历,吃算力)。
- 构建完成后,索引文件(质心 / 编码 / 图边 + 内部 ID,不是完整向量)序列化写回对象存储。
- QueryCoord 通知各 QueryNode 加载新索引;此后该段检索走 ANN,未就绪前走暴力。