第 3 篇 建立了 Growing / Sealed 状态机。实时可搜的关键不在「又一个 HNSW 参数」,而在:写操作先以 Message 形式进入以 WAL 为中心的 Streaming Service,提交后才能在 Growing 路径上被搜到。
本文按官方 Streaming Service 与 Woodpecker 文档,钉住 Streaming 子系统的组件、Message/TSO 顺序、WAL 生命周期,以及 2.6 引入的 Woodpecker 相对 Kafka/Pulsar 的设计目标。不展开 Sealed 上 Knowhere 建索(第 8、10 篇)。
本文是「向量检索引擎」系列第 5 篇(共 18 篇)。→ 系列目录
版本锚定:Milvus 2.6.x Streaming Service、Woodpecker、Architecture Overview、Data Processing。
一、Streaming Service 三件套
官方定义 Streaming Service 为围绕 WAL 的内部流式模块,支撑:摄入/订阅、集群状态故障恢复、流式数据转历史数据、Growing 数据查询。架构上三部分:
| 组件 | 位置 | 职责 |
|---|---|---|
| Streaming Coordinator | Coordinator 内的逻辑组件 | 用 etcd 发现 Streaming Node;绑定 WAL 与节点;暴露 WAL 拓扑供客户端选路 |
| Streaming Node 集群 | Worker | WAL append、状态恢复、Growing 查询等流式处理 |
| Streaming Client | 内部客户端 | 服务发现、就绪检查;发起写与订阅 |
Access Layer 的 Proxy 通过这套服务把 DML 送到正确的 Streaming Node(第 1 篇 API 路径表)。
二、Message 与 TSO:日志即写顺序
Streaming Service 是 日志驱动:Milvus 中的写操作(DML 与 DDL)被抽象为 Message。
- 每条 Message 由 Streaming Service 赋予 Timestamp Oracle(TSO) 字段,表示其在 WAL 中的顺序。
- Message 顺序决定写操作顺序,从而可以从日志重建最新集群状态。
- 每条 Message 属于特定 VChannel,并在该 channel 内维持不变量(例如同一 channel 上 Insert 必须出现在对该集合的 DropCollection 之前)。
Data Processing 补充:Streaming Node 在写入底层 WAL 前对 payload 做一致性检查;一旦持久提交到 WAL,即保证不丢——崩溃时通过 replay 恢复 pending 操作。
这与经典数据库「先日志后数据」同构,但作用域是 VChannel / shard,不是单机一个 redo 文件。多 WAL、水平扩展的含义见下一节。
三、WAL 组件:多日志、单所有者、段生命周期
为支撑大规模水平扩展,官方明确:Milvus 的 WAL 不是单一日志文件,而是多个日志的复合;每个日志可独立服务多个 VChannel。约束:
- 任一时刻,一个 WAL 组件只允许在一个 Streaming Node 上运行。
- 该约束由底层 WAL 存储的 fencing 与 Streaming Coordinator 共同保证。
WAL 组件的其它能力(官方列举):
- Segment 生命周期管理:按内存、segment 大小、空闲时间等策略管理(与第 3 篇 flush 衔接)。
- 基本事务支持:单条 Message 有大小限制时,提供 VChannel 级原子写。
- 高并发远程日志写:支持第三方远程消息队列作 WAL 存储;用并发写提升吞吐,靠 TSO 与 TSO 同步维持顺序,按 TSO 顺序读回。
- Write-Ahead Buffer:写入 WAL 后暂存在缓冲中,支持尾读而无需每次打远程存储。
- 多种 WAL 后端:Woodpecker、Pulsar、Kafka;Woodpecker 零本地盘模式可去掉对远程消息队列的依赖。
3.1 Recovery Storage
Recovery Storage 总是运行在持有对应 WAL 的那个 Streaming Node 上。职责:
- 把流式数据转为持久化历史数据,写入 对象存储;
- 负责该节点上 WAL 组件的内存状态恢复。
这是 Growing → 对象存储上 Sealed 的桥梁之一(细节与 flush 策略见第 3、6 篇)。
3.2 Query Delegator
每个 Streaming Node 上的 Query Delegator 负责 单个 shard 上的增量查询:
- 生成查询计划;
- 将请求转发给相关 Query Node;
- 聚合结果;
- 向其它 Query Node 广播 Delete。
Delegator 与 WAL 组件共存于同一 Streaming Node。若 Collection 配置多副本,则另有 \(N-1\) 个 Delegator 部署在其它 Streaming Node 上(官方 Streaming Service)。
这解释了第 3 篇的查询落点:Proxy → Streaming Node(Delegator)→ 本地 Growing + 远程 Sealed。
3.3 WAL 迁移与 Wait for Ready
存算分离使 WAL 可从一节点迁到另一节点。迁移时:旧节点会拒绝部分请求;新节点恢复 WAL;客户端 Wait for Ready,直到新节点上的 WAL 可服务。排障「写入短暂失败 / 查询抖动」时应考虑是否与 WAL 迁移窗口重合(第 14、17 篇)。
四、Woodpecker:云原生 WAL
Milvus 2.6 引入 Woodpecker 作为专用云原生 WAL,设计目标(官方 Woodpecker):云环境高吞吐、可靠 append-only 恢复、无本地盘 / 无外部 broker 的运维面。
4.1 零本地盘
- 日志数据存放在云对象存储(如 S3、GCS 等);
- 元数据由 etcd 一类分布式 KV 管理;
- 核心路径不依赖本地磁盘。
组件:Client、LogStore(缓冲、异步上传、日志 compaction)、Storage backend、etcd。
4.2 两种部署模式
| 模式 | 机制(官方) | 适用直觉 | 官方给出的延迟量级 |
|---|---|---|---|
| MemoryBuffer | 客户端内嵌缓冲,周期性刷到对象存储;etcd 管元数据 | 偏批、要简单、可接受较高写延迟 | 写延迟一般 200–500 ms |
| QuorumBuffer | 与三副本 quorum 交互;至少写成功到 2/3 后视为成功,再异步刷对象存储 | 低延迟、高耐久 | 典型 个位数毫秒 完成 quorum 确认 |
以上延迟数字来自 官方文档对模式的描述,不是本机实测。选型时应以自身负载复测为准。
4.3 官方吞吐对照(引用,非本机复现)
Woodpecker 文档给出单节点、单客户端、单日志流设置下的对照表(单位与条件以原文为准):
| System | Kafka | Pulsar | WP Minio | WP Local | WP S3 |
|---|---|---|---|---|---|
| Throughput | 129.96 MB/s | 107 MB/s | 71 MB/s | 450 MB/s | 750 MB/s |
| latency | 58 ms | 35 ms | 184 ms | 1.8 ms | 166 ms |
文档同时给出测试机上后端理论吞吐上限(MinIO ~110 MB/s、本地盘 600–750 MB/s、单 EC2 上 S3 最高约 1.1 GB/s),并称 Woodpecker 达到各后端最大可能吞吐的约 60–80%。
引用规则:这些是 厂商文档基准,硬件、对象存储实现、并发模型与你的集群不同则不可直接当容量规划。本系列不在未复现前改写或「约等于」这些数字。
4.4 争论:自研 WAL vs Kafka/Pulsar
| 立场 | 主张 | 代价 |
|---|---|---|
| 沿用 Kafka/Pulsar | 运维栈成熟、生态工具多 | Milvus 额外依赖消息系统;资源与版本耦合 |
| Woodpecker 零盘 | 降外部依赖、贴对象存储扩缩 | 新组件成熟度、延迟模式(MemoryBuffer vs Quorum)要单独理解 |
Architecture Overview 仍列出 Kafka、Pulsar、Woodpecker 为常见 WAL 实现——不是强制唯一后端。生产选择应写清:一致性需求、可接受的写延迟、是否已有消息队列团队。
五、学术谱系与工程间隙
5.1 谱系
| 阶段 | 概念 | 在本篇的落点 |
|---|---|---|
| ARIES / 数据库 WAL | 先日志后数据、崩溃恢复 | Message 提交到 WAL 后不丢;replay |
| 分布式日志 | Kafka 等共享日志 | Milvus 可插拔远程 WAL;多日志水平扩展 |
| 云原生 WAL | Woodpecker 零本地盘 | 日志直接(或经 quorum)面向对象存储 |
Wang et al. (SIGMOD 2021) 强调动态更新与查询并存;2.6 的 Streaming Node + Woodpecker 是该目标在工程上的一轮重构——以官方 2.6 文档为准,不要把 2021 论文组件名硬套过来。
5.2 工程间隙
- 「实时可搜」指 WAL 提交后进入 Growing 查询路径,不等于 Sealed 索引已建完。
- MemoryBuffer 官方写明写延迟可达数百毫秒量级——与「毫秒级 RAG」营销话术可能冲突,需在架构评审里单独确认模式。
- QuorumBuffer 降本地状态,但仍有 quorum 成员与对象存储异步刷盘两段;故障模式与「本地盘 WAL」不同。
5.3 开放问题
- 多租户下 WAL 迁移频率与尾延迟的可接受上界如何制度化测量?
- Woodpecker 相对 Kafka 的运维成本,在「已有 Kafka 平台」的组织里是否总是净收益?
- Delete 经 Delegator 广播到 Query Node 与 Growing 可见性之间的窗口,如何在一致性级别下解释(第 12–13 篇)?
六、小结
Streaming Service 把写入变成 带 TSO 的 Message 流;WAL 多日志、单所有者;Streaming Node 上的 Delegator 把 Growing 本地搜 与 Sealed 远程搜 接成一次 shard 查询。Woodpecker 用零本地盘目标降低对外部 broker 的硬依赖,但 MemoryBuffer / QuorumBuffer 的延迟语义必须按官方模式理解,吞吐表只作引用。
下一篇看对象布局:对象存储上的 Segment 布局;或进入执行层:Query Node 与 Segcore。
参考资料
- Milvus Documentation v2.6.x, Streaming Service(Coordinator、Node、Client、Message、WAL、Recovery Storage、Query Delegator、Wait for Ready)。
- Milvus Documentation v2.6.x, Woodpecker(零盘、MemoryBuffer/QuorumBuffer、官方基准表)。
- Milvus Documentation v2.6.x, Architecture Overview、Data Processing。
- Wang et al., Milvus: A Purpose-Built Vector Data Management System, SIGMOD 2021。
- 第 3 篇 Segment 状态机、系列 index。
返回 系列目录 | 上一篇:Proxy 与 Coordinator | 下一篇:对象存储布局
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【向量检索引擎】Proxy 与 Coordinator:接入面、TSO 与集群大脑
按 Milvus 2.6.x 四层架构拆解无状态 Proxy 的校验与 MPP 归并,以及单活跃 Coordinator 的 DDL/TSO、Streaming 绑定、Query 拓扑与离线任务调度;说明控制面与 Worker 的分工边界。
【向量检索引擎】分布式 search 归并:Delegator、多级 reduce 与 GuaranteeTs
按 Milvus 2.6.x Data Processing 与 Architecture 拆解 search 的多级归并树:Proxy → Streaming Node Delegator → Query Node 段级结果;说明 shard 并发、Top-k 合并直觉,以及 GuaranteeTs/ServiceTime 如何让一致性变成等待。
【向量检索引擎】一致性模型:Strong 到 Eventually 与 GuaranteeTs
按官方 Consistency Level 与 Timestamp 文档说明 Strong/Bounded/Session/Eventually 如何映射到 GuaranteeTs,ServiceTime 等待如何影响尾延迟,并对照 2.6 Growing/Sealed 分流下的「刚写入就能搜到」精确含义。
【向量检索引擎】副本、负载与故障恢复:内存副本与 WAL 迁移
按官方 In-Memory Replica 与 Streaming Service 说明副本组、shard/historical 副本、Proxy 缓存与 failover;对照 2.6 Streaming Delegator 多副本,以及 WAL Wait for Ready 与 handoff 负载均衡。