Milvus 3.0 开源解读|从Kafka、Pulsar到Woodpecker,数据库如何低延迟、低成本的写入
对于现代数据库而言,WAL(Write-Ahead Log,预写日志)是保证数据可靠性和写入性能的重要基础设施。随着数据库架构不断演进,越来越多系统开始将 WAL 从数据库进程中解耦,交由 Kafka、Pulsar、BookKeeper 等分布式日志基础设施承载。
这些系统诞生于传统 IDC 时代,在过去十多年支撑了大量数据库和流式应用的发展。随着公有云逐渐成为数据库部署的重要方式,它们也不断演进,引入对象存储、Tiered Storage 等能力来适应新的基础设施。不过,受限于原有架构,在跨可用区网络成本、对象存储利用率以及弹性伸缩效率等方面,仍然存在进一步优化空间。
Milvus 的 WAL 架构也在持续演进:从单机 RocksMQ,到集群 Kafka/Pulsar,再到今天的 Woodpecker(啄木鸟)。作为 Milvus 原生、专为云设计的 WAL 服务,Woodpecker 借鉴了 BookKeeper 的分布式日志模型,同时结合对象存储和云网络特性,对数据路径进行了重新设计,在跨可用区部署、对象存储利用和成本控制等方面进行了进一步优化。
为什么说 Milvus + Woodpecker 是更"云原生"的组合?看它的两种模式就明白了。
模式一:Embed 模式(2.6 已发布)
第一种是 Embed 模式,Milvus 2.6 就已经上线。它本质上是在内存中攒批后直接写入对象存储:数据在内存里攒一小批,直接写进对象存储,不需要额外运行 Kafka、Pulsar 这类常驻日志服务集群。
好处非常直接——几乎没有额外的基础设施成本,你只需要为存储介质本身付费,钱全花在刀刃上。代价是延时会高一点,因为攒批意味着要等一个小小的时间窗口。
所以它适合那些"更在意整体吞吐、不那么在意单条延时"的业务。如果你的场景正好是这样,Embed 模式几乎是最优解,额外基础设施成本趋近于 0。
但问题来了:如果我既要成本低、又要延时低呢?难道只能退回去用 Pulsar?——这正是 Milvus 3.0 要回答的问题。
模式二:Service 模式(3.0 新功能)
第二种,就是 Milvus 3.0 新发布的 Woodpecker Service 模式。它在延时和成本之间做了更聪明的权衡:延时压了下来,成本依然非常可控。秘诀主要在以下几个地方。
一是1RTT多副本写。 Woodpecker 采用 client-driven replication,由客户端负责协调一次写入涉及的多个副本,并在一个 RTT 内完成 quorum 写入。跨 AZ 网络流量固定为2份副本的数据量。而传统日志系统通常需要先经过 Broker 或 Leader 节点,再完成多副本复制, 这个过程有1份数据可能2/3概率跨可用区,2份是固定的跨可用区流量费用。相比 Woodpecker 固定两份副本跨 AZ 网络流量,传统方案理论上约增加三分之一的跨 AZ 网络流量。
二是就近直读。 Service 模式是拓扑感知(topology-aware)的,每次读取都尽量读离自己最近的副本,而且是单跳直读(single-hop read)。相比需要经过 Broker 转发的数据路径,Woodpecker 可以直接访问目标副本,减少中间转发带来的额外延迟。
很多日志系统读取时需要经过 Broker 等中间层,并且不会优先选择同 AZ 的副本进行读取,读取可能是随机的节点/副本, 这样算下来每次读有2/3概率跨可用区,中间的跨可用区流量费用不可忽略。
三是Segment Rolling 后立即上传对象存储。 很多类似系统为了用上 S3/OSS 的低价,会把一部分 MQ 数据传到对象存储,但它们本来不是为云设计的,需要维护对象存储与本地存储之间的数据映射和元数据,两套存储之间的数据一致性维护更加复杂。Woodpecker 不一样:首先在日志流中进行segment分片,每个 Segment 都维护完整的生命周期状态,因此能够明确知道当前位于本地还是对象存储;Segment Rolling 后即可将整个 Segment 上传到对象存储,本地盘占用压到最低,存储成本也跟着降下来。
四是副本不依赖节点之间持续的数据复制。 传统 IDC 的多副本,是节点之间互相拷一份一致的数据,这在云上很不友好——跨 AZ 要收费,节点 failover 又频繁(云上还常用 spot 这类随时可能被回收的机型)。来回拷贝既慢又贵,还给单点带来压力。Woodpecker 干脆不这么干,而是将日志持久化到对象存储,由对象存储承担共享存储的角色。这样的设计有三个直接收益:
- Failover 时无需整节点复制数据,只需将存活副本及时上传对象存储即可快速恢复副本,而无需等待整节点数据复制完成。
- 对象存储具备几乎无限扩展能力,不再受节点间复制带宽限制。
- 大规模节点替换时,不会出现整节点数据重新复制导致的网络、磁盘洪峰。
这套云原生设计带来的收益是实打实的:在典型三副本跨 AZ 部署下, 同等硬件下写入延时仍保持毫秒级,与传统三副本本地盘方案处于同一量级。在跨可用区部署时,写入还能节省约1/3跨可用区流量费用,读取则节省约2/3流量费用。存储则看设置的消费位点和业务写入流量不同场景来比较成本,核心是这个时间段内对象存储成本和三副本本地盘成本的价差。例如 AWS GP3 三副本与 S3 的单位存储成本约相差 15 倍。当日志能够在 Segment Rolling 后及时迁移到对象存储时,长期保存在本地 SSD 的数据量显著减少,在持续写入场景下可以节省大量存储成本。
以持续稳定写入 20 MB/s、保留本地盘 72 小时为例:
存储成本差价1650美元每月:
| 方案 | 成本 |
|---|---|
| GP3 三副本 | 1800 美元 |
| S3 | 115 美元 |
写入路径理论上可减少一个副本的2/3概率跨网络流量,同样以20MB/s稳定写入流量为例,即每月写入流量费用节省:20MB/s * 1个月 * 0.02$/GB * 2/3 = 1036美元
读取路径理论上可减少约 2/3 的跨可用区网络流量费用,即每月读取流量费用节省:20MB/s * 1个月 * 0.02$/GB * 2/3 = 1036美元
| 注: 当然不同场景可以设置不同的消费位点来节省存储的费用,但毕竟是两套系统,即使设置的只有1个小时后上传对象存储,如果这1个小时内上传的速度足够快(1GB/s),这个数据量依然会保持很高(3.5TB),这个成本依然随着使用的方式有波动,这都是因为它们不基于云存储设计导致的底层技术原因。Woodpecker 则不同,写入再快也会按照 Segment Rolling 策略持续切分日志,并及时上传对象存储,即使发生突发写入,本地磁盘中长期保留的数据也仅限于最近尚未 Rolling 的少量 Segment。 |
|---|
按照 AWS US East(2026-06-30)价格计算: GP3:0.12 美元 / GB-month, S3 Standard:0.023 美元 / GB-month
AWS 跨可用区发送方与接收方分别收取0.01 美元/GB,综合成本为0.02美元/GB
怎么用?一行命令开箱即用
在 Milvus 3.0 里开启 Woodpecker Service 模式很简单,一行 helm 命令就够了,核心就是把 service 模式的开关打开:
helm upgrade -i my-release zilliztech/milvus \
--set image.all.tag=v3.0-beta \ # 镜像 tag 等以 3.0 正式版为准
--set streaming.enabled=true \
--set streaming.woodpecker.embedded=false \
--set woodpecker.enabled=true \
--set woodpecker.image.tag=v0.1.33 # 镜像 tag 等以 最新woodpecker镜像为准
不需要你额外搭一套 Kafka/Pulsar,也不用操心它怎么跟着 Milvus 一起弹性伸缩。
从 Embed 到 Service,Woodpecker 的两种模式覆盖了从"极致省钱"到"又快又省"的不同需求,而它们共同的底色,都是为云而生。更多 embed/service 模式的用法和调优,可以关注 Milvus 官方文档里的 Woodpecker 章节。






