Streaming Node 解决 提交与实时可搜(第 5 篇);Query Node 解决 历史段检索(第 7 篇)。重型、可延迟的工作——向量/标量索引构建与 历史数据整理(compaction)——落在 Data Node,由 Coordinator 调度(第 4 篇)。
本文是「向量检索引擎」系列第 10 篇(共 18 篇)。→ 系列目录
版本锚定:Milvus 2.6.x Architecture / Data Processing(A 级)。compaction 动机的历史叙述引用官方博客(B 级)。
一、Data Node 在四层中的位置
官方定义:Data Node 负责历史数据的 离线处理,例如 compaction 与 index building。它是存算分离下的无状态 Worker:听 Coordinator 指令,读写对象存储,不永久持有可变用户状态。
与另外两类 Worker 的分工:
| Worker | 在线性 | 典型工作 |
|---|---|---|
| Streaming Node | 在线写 + Growing 查询 | WAL、flush、Delegator |
| Query Node | 在线历史查询 | 加载 Sealed、段级 search |
| Data Node | 离线 | 建索、compaction |
Architecture 插入流的末步:Data Node 在 Sealed 上建索引并写入对象存储后,Query Node 加载新索引并替换对应增长数据视图——中间由 Coordinator handoff 缝合(第 3 篇)。
二、Index build:每段一份索引
Data Processing · Index building(A 级要点):
- 为避免数据一更新就全局重建,Collection 再分为 segment,每段自有索引。
- 可为向量字段、标量字段、主键字段建索引。
- 输入与输出都经对象存储:Data Node 加载段日志快照 → 反序列化 → 建索 → 序列化 → 写回对象存储。
- 向量建索是计算与内存密集、依赖 SIMD;官方强调弹性对成本的重要性。
这与 Knowhere「对 segment 内数据 train 并 build」(第 8 篇)直接对接:Data Node 是调度与 I/O 壳,Knowhere 是向量索引内核。
flowchart LR
coord["Coordinator schedule"]
dn["Data Node"]
obj["Object storage"]
know["Knowhere Train/Build"]
qn["Query Node load"]
coord --> dn
obj -->|"load snapshot"| dn
dn --> know
know -->|"write index"| obj
coord -->|"handoff"| qn
obj --> qn
2.1 新鲜度与「有数据无好索引」
flush 已使数据进入 Sealed 并可能被查询路径看到,但
ANN
索引对象可能仍在构建队列中。此时执行可能退化为更慢的路径或临时索引策略(具体行为随版本与
queryNode.segcore.interimIndex.*
等配置变化,见官方 Query Node 配置;第 7
篇提及)。排障「写入后能搜但很慢 / 召回不稳」应同时看:
- 建索任务是否堆积(Data Node / Coordinator);
- Query Node 是否已加载对应索引(handoff / data view)。
三、Compaction:清理与合并
3.1 动机(历史官方叙述)
官方博客 How to Compact Data in Milvus?(2022,B 级)将 compaction 概括为:合并小段、清理逻辑删除,降低存储占用;由协调组件触发、Data Node 执行。并区分:
- binlog compaction:段内 insert/delta 类日志整理,使已删实体不再占用有效日志内容;
- segment compaction:多个 Sealed 小段合并成更大段。
这与列存 merge、LSM compaction 同属「不可变文件 + 后台整理」家族(对照 columnar-engine、rocksdb),但整理目标还包括 软删空间回收 与 段数可控(段数影响第 9 篇归并扇出与第 6 篇对象 API 次数)。
3.2 与 handoff 的衔接(A 级)
Data Processing:当 Growing flush 成 Sealed,或 Data Node 完成 compaction 后,Coordinator 发起 handoff,重新分布 Sealed 到 Query Node,并释放冗余。
因此 compaction 不是「只在桶里改文件」:它会驱动 查询视图迁移。compaction 高峰期可能与查询加载争抢对象存储带宽与 Node CPU。
3.3 实现提示(不替代源码阅读)
Data Node compaction 实现中可见对
SegmentBinlogs 的计划驱动合并、可选 merge-sort
等分支(源码路径随 release 变化)。本系列不绑定某一 commit
的函数名表;升级时以当前
internal/datanode/compactor
与官方发布说明为准。
四、资源与调度:离线队列如何拖累在线 SLO
Coordinator「Historical Data Management」把 compaction 与建索当作可分发任务。工程上常见张力:
| 张力 | 表现 |
|---|---|
| 建索慢于写入 | 索引堆积;查询走劣路径或等待 |
| compaction 落后 | 小段爆炸;删除空间不回收;对象文件数上升 |
| 与查询争抢 | Query Node 加载与 Data Node 拉取同一桶前缀 |
容量规划应把 Data Node 当成 独立池:不能假设「加 Query Node」自动消化建索队列。
五、学术谱系、工程间隙、开放问题
5.1 谱系
| 工作负载 | 经典机制 | Milvus 落点 |
|---|---|---|
| 不可变文件整理 | LSM compaction / 列存 merge | Data Node compaction |
| 批量构建索引 | 离线 ANN 构建流水线 | 每 Sealed segment 建 Knowhere 索引 |
| 视图切换 | 快照发布 / handoff | Coordinator handoff |
Wang et al. (SIGMOD 2021) 强调动态更新与查询并存;2.6 用 Streaming/Query/Data 三分把「在线可搜」与「离线重活」拆开,避免在查询节点上同步跑满 SIMD 建索。
5.2 工程间隙
- 博客中的触发阈值、
MaxSegmentSize倍数等是历史叙述;以当前版本配置与监控为准,勿把 2022 默认值当 2.6 真理。 - 「每段一索引」简化全局重建,但使 段数 ≈ 索引任务数;盲目调小段大小会制造建索风暴。
- 对象存储按请求计费时,compaction 重写放大的是 钱与 API,不只是 CPU。
5.3 开放问题
- 建索优先级如何相对 compaction、相对查询加载自动调度?
- GPU 建索与 CPU 查询并存时的集群分区策略(第 8、18 篇)?
- 多向量字段导致单段多索引时,部分索引成功部分失败的对外语义?
六、小结
Data Node 是离线臂膀:从对象存储拉 Sealed 快照,经
Knowhere 写回索引,并做 compaction
控制段数与删除空间;Coordinator handoff 把结果交给 Query
Node。在线 SLO 往往死在
离线队列与对象存储争用,而不是又一个
ef 参数。
下一批进入过滤与一致性语义(第 11–14 篇);对照与选型见第 15–18 篇。
参考资料
- Milvus Documentation v2.6.x, Architecture Overview / Storage/Computing Disaggregation(Data Node 职责)。
- Milvus Documentation v2.6.x, Data Processing(index building、handoff 与 compaction 触发叙述)。
- How to Compact Data in Milvus?, Milvus Blog, 2022(binlog/segment compaction;B 级)。
- Wang et al., SIGMOD 2021。
- 第 3、4、6、8 篇、系列 index。
返回 系列目录 | 上一篇:分布式 search 归并 | 下一篇:混合过滤
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【向量检索引擎】Collection · Partition · Segment · Channel:Growing 到 Sealed 的状态机
钉住 Milvus 2.6.x 的数据模型词汇:Collection/Partition、vchannel/pchannel 与 Streaming Node 绑定,Growing/Sealed 段类型、flush 与 handoff,为后续写路径与读路径提供共同状态机。
【向量检索引擎】Query Node 与 Segcore:段级 search 如何执行
按 Milvus 2.6.x Data Processing 与 Architecture 拆解 Query Node 对 Sealed 的加载与段级检索,说明 Streaming Node 上 Growing 路径与 Query Delegator 如何拼成一次 search,并界定 Segcore 与 Knowhere 的层次。
【向量检索引擎】Delete · Upsert · TTL:软删、覆盖写与过期回收
按官方文档说明 delete(主键/过滤)、upsert(override/merge)、collection TTL 的语义;结合 bitset 软删与 compaction 物理回收,划清「搜索不可见」与「对象存储已清理」的时间差。
【向量检索引擎】副本、负载与故障恢复:内存副本与 WAL 迁移
按官方 In-Memory Replica 与 Streaming Service 说明副本组、shard/historical 副本、Proxy 缓存与 failover;对照 2.6 Streaming Delegator 多副本,以及 WAL Wait for Ready 与 handoff 负载均衡。