Sealed 段「不可变且落在对象存储」是 第 3 篇 的定义;Query Node「从对象存储加载历史数据」是 第 7 篇 的前提。本文回答:对象存储里 大致存什么、flush/建索如何读写它,以及为何在 S3 类存储上 文件切分方式会支配延迟。
本文是「向量检索引擎」系列第 6 篇(共 18 篇)。→ 系列目录
版本锚定:Milvus 2.6.x Architecture / Data Processing(A 级)。Storage V1→V2 布局演进引用官方工程博客(B 级),数字为原文陈述,非本机复现。
一、存储三件套里的对象存储
官方四层把持久化拆成:
| 组件 | 存什么 | 要求 |
|---|---|---|
| Meta(etcd) | schema 快照、消费 checkpoint;服务注册与健康检查 | 高可用、强一致、事务 |
| WAL | 提交前的写日志(Kafka / Pulsar / Woodpecker) | 耐久、可 replay(第 5 篇) |
| Object storage | 日志快照、标量与向量的索引文件、查询中间结果 | 便宜、可扩展;官方同时指出 高访问延迟、按请求计费 |
Milvus 默认常用 MinIO,并可部署到 AWS S3、Azure Blob 等。对象存储不是「又一块本地盘」,而是 高延迟随机打开的共享字节池——这决定了段文件布局必须减少小文件与 API 次数。
二、从 Growing 到对象上的 Sealed
Data Processing 路径(与第 3、5 篇对齐):
- Streaming Node 将 WAL 提交条目切成 Growing;
- flush 后数据持久化到对象存储,形成 不可变 Sealed;
- Data Node 从对象存储加载该段快照,建索引,再把索引写回对象存储;
- Query Node 按 handoff 结果加载段数据与索引。
因此对象存储上至少有两类读者关心的对象族:
- 段数据快照(官方称 log snapshots / 持久化后的 segment 数据);
- 索引文件(向量与标量;每段可有自己的索引)。
中间查询结果亦可落对象存储(Architecture)——多用于大结果或特定执行路径,本篇不展开为默认热路径。
flowchart LR
wal["WAL commit"]
grow["Growing"]
obj["Object storage<br/>Sealed snapshot"]
idx["Index files"]
qn["Query Node load"]
wal --> grow -->|flush| obj
obj -->|DataNode build| idx
obj --> qn
idx --> qn
三、布局演进:按字段拆分 vs 按段整合
3.1 经典叙述:segment 内多 binlog
较早的工程叙述与源码路径仍大量出现
binlog
一词:段内用多份二进制日志/列文件记录插入与变更;compaction
处理 insert/delta binlog 与小段合并(历史博客 How to
Compact Data in Milvus?,B 级)。Data Node compaction
源码计划里仍可见 SegmentBinlogs /
FieldBinlogs 一类结构——说明 「段 → 字段
→ 文件列表」 的元数据模型长期存在。
3.2 Storage V2:段级 Parquet 与 API 次数
官方工程博客 Data Addressing Deep Dive(2026-03,B 级)将对象存储性能归结为:
\[ \text{寻址代价} \approx \text{元数据访问次数} + \text{数据访问次数} \]
并对比 Milvus 存储布局演进(原文表格摘要):
| 方面 | V1(按字段拆分) | V2(按段整合) |
|---|---|---|
| 文件组织 | 字段各自 binlog | 以 segment 为单位整合 |
| 格式 | 自定义 binlog | Parquet(文中亦提及可支持 Lance、Vortex) |
| 统计信息 | 独立 stats_log | 嵌入 Parquet footer |
| 原文给出的量级感受 | 字段×段导致海量小文件、查询可触发极多 S3 API | API 次数数量级下降、延迟从「分钟级感受」落到「秒级感受」 |
博客用「100 字段 × 1000 段」的思想实验说明 V1
小文件爆炸;V2 按段、按列组(column
group)收敛文件数。这些倍数与「分钟/秒」是原文叙述,不是本站实测;读者应在自己的
MinIO/S3 上用段数×文件数核对
LIST/GET 次数。
3.3 与 2.6 写路径的关系
社区变更说明(如强制新写走 StorageV2 的 PR 叙述)表明 2.6 线将新写入统一到更新布局。本系列结论只取可核对的工程含义:
- 对象存储友好布局 = 减少小文件与按请求计费;
- Query Node 加载与 Data Node 建索的输入输出都围绕「段在对象上的快照 + 索引对象」;
- 具体键前缀、列组切分以当时 release 的 storage
实现为准——排障时用对象浏览器/
mc ls看 每段文件个数,比背路径模板更有用。
四、索引对象与数据对象的生命周期差
建索流程(Data Processing,A 级):
- Data Node 从对象存储加载待建索段快照到内存;
- 反序列化数据与元数据,调用索引构建(Knowhere,第 8 篇);
- 序列化索引,写回对象存储。
因此可能出现:
- 数据 Sealed 已可被暴力/临时路径搜索,向量索引对象尚未写完;
- compaction 产出 新段快照,旧段与旧索引在 handoff 与 GC 策略下延迟回收。
「磁盘上有索引文件」≠「Query Node 已加载该索引」——后者还取决于 Coordinator 的 data view(第 4、10 篇)。
五、与湖仓对象布局的一句对照
lakehouse 里
Iceberg/Parquet 优化的也是对象存储上的 清单 +
文件剪枝。lakehouse/21
显示 Lance 在随机 take 上相对 Parquet
的优势。Milvus 的对象布局服务的是 ANN
段生命周期与索引文件,不是通用表格式事务。二者可共享同一对象桶,但
元数据权威不同——不要假设 Iceberg snapshot
与 Milvus segment 视图自动一致(第 16、18 篇)。
六、学术谱系、工程间隙、开放问题
6.1 谱系
| 问题 | 经典应对 | 在本篇的落点 |
|---|---|---|
| 共享存储上的小文件 | 合并文件、列组、清单 | StorageV2/Parquet 段布局(B 级博客) |
| 不可变数据 + 后台整理 | LSM compaction、列存 merge | Data Node compaction(第 10 篇) |
| 寻址代价 | 元数据分层、缓存、剪枝 | 官方博客的 addressing 框架 |
6.2 工程间隙
- Architecture 承认对象存储延迟高、按请求收费,并提到未来用内存/SSD 冷热池——生产上缓存命中率往往比「换一种索引类型」更能打延迟。
- LIST 大量前缀本身可成瓶颈;监控对象侧 API 错误率与慢请求,不要只看 Knowhere QPS。
- 多副本 Query Node 可能重复从对象存储拉取同一 Sealed——副本换延迟,放大 GET 次数(第 14 篇)。
6.3 开放问题
- 段大小、列组策略与 S3 计费模型如何联合优化?
- 索引文件与数据快照分桶/分存储类(IA/Archive)时,handoff 延迟如何建模?
- 与 Iceberg 共用桶时,生命周期策略误删索引前缀的防护?
七、小结
对象存储保存 Sealed 快照、索引与部分中间结果;etcd 管元数据,WAL 管提交。布局从「按字段碎文件」走向「按段整合(Parquet 等)」的核心动机是削减对象 API 次数。下一篇把多段候选如何收成一次响应:分布式 search 归并。
参考资料
- Milvus Documentation v2.6.x, Architecture Overview / Storage/Computing Disaggregation(Object storage 职责与代价)。
- Milvus Documentation v2.6.x, Data Processing(flush、index building 读写对象存储)。
- Bill Chen, Data Addressing Deep Dive: From HashMap to Milvus, Milvus Blog, 2026-03(Storage V1/V2;B 级)。
- How to Compact Data in Milvus?, Milvus Blog, 2022(binlog/segment compaction 历史叙述;B 级)。
- 第 3、5、7 篇、lakehouse/21。
返回 系列目录 | 上一篇:Proxy 与 Coordinator | 下一篇:分布式 search 归并
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【向量检索引擎】Collection · Partition · Segment · Channel:Growing 到 Sealed 的状态机
钉住 Milvus 2.6.x 的数据模型词汇:Collection/Partition、vchannel/pchannel 与 Streaming Node 绑定,Growing/Sealed 段类型、flush 与 handoff,为后续写路径与读路径提供共同状态机。
【向量检索引擎】Lance / LanceDB 对照:格式还是服务
承接 lakehouse/21 的 Lance vs Parquet 实测口径,划清湖原生向量格式与 Milvus 专用引擎的边界:随机 take、ANN 随数据集管理、版本化,以及何时不必上向量集群。
【数据湖与开放表格式】对象存储语义与代价
对象存储不是网络版 POSIX 文件系统。本文用 S3 官方语义钉住四件事:强一致模型的边界、LIST 随对象数线性增长的代价、没有原子 rename(只能 copy+delete)、条件写(If-None-Match/If-Match)对提交协议的意义,并讲清 multipart 与对象不可改写。
【向量检索引擎】向量引擎全景:算法、RAG 与专用引擎之间的一层
定位专用向量检索引擎相对 ANN 算法、RAG 应用与湖仓格式的分工;以 Milvus 2.6.x 四层架构给出本系列 18 篇地图,并交代从 SIGMOD 2021 系统论文到存算分离演进的谱系。