教程:如何做 Milvus CDC 主备搭建,实现集群级灾备、零业务中断
对云上客户来说,Zilliz Cloud 提供成熟的 Global Cluster 能力,可以帮助他们一键实现跨地域、跨集群的高可用容灾,大幅降低云上运维成本。但考虑到在实际生产中,大量企业基于安全与合规要求,会采用开源私有化、本地机房离线部署模式,无法使用云端托管的高阶能力。为此,我们将支撑 Global Cluster 跨区域复制的核心能力 ——Milvus CDC 组件全面开源。
本文将完整讲解开源环境下,如何基于 CDC 快速搭建主备复制架构,补齐机房级、集群级灾难容错能力,助力私有化部署业务平稳运行。
文|戴一豪、卢忆卿、黄浩原
这个世界,黑天鹅越来越多,企业如果只把数据放在不同篮子,很可能,下一秒货架就塌了。
过去,各类云原生开源数据库,在做底层架构设计时,就会将针对单节点故障做优化设计,有效保障日常数据存储与检索的稳定性。
但在实际生产环境中,各类超出单节点故障范围的灾难性事件还是会经常发生,直接影响整个集群甚至数据中心,给业务带来不可挽回的损失。
比如K8s集群导致所有Pod被驱逐,集群整体瘫痪;比如超过限高的卡车撞断数据中心出局光缆,导致集群网络中断;比如配电系统遭遇雷击,引发数据中心整体失电,所有设备停运;再比如,数据中心暖通空调系统被柳絮堵塞,设备过热宕机。
总之,活得久了,别说光缆挖断导致业务中断,就是战争的不可抗力导致机房损毁,在这几年也已经见怪不怪。
面对这类跨节点、跨集群甚至跨数据中心的故障,单一的节点级容错机制已无法满足需求。为此,Milvus设计了分层高可用策略组合,通过不同层级的容灾方案,覆盖不同范围的故障域,为业务数据安全提供全方位保障。
01
Milvus分层高可用策略解读
Milvus 的高可用策略是分层设计的,不同层级策略可以应对不同的故障域:
节点/AZ 级容灾:多副本,将 Segment 数据加载到多个 QueryNode,发生节点发生故障时查询请求自动路由到其他健康副本,实现零数据丢失、瞬时恢复。
集群/Region 级容灾:CDC 主备复制 ,通过消费 WAL 日志流,将增量数据异步复制到独立的备集群,备集群持续热备且可承担读流量。
最后兜底:定期备份,通过 Milvus Backup 周期性创建快照,并将备份数据复制到不同 Region ,不同的云服务商,或者不同介质的存储设备上。

这三层策略是互补关系,生产环境中,我们可以根据自身的需求和成本承受能力选择和组合采用不同的策略。
本篇文章,我们将重点讲述CDC 主备复制方案。
02
什么是Milvus CDC?
CDC(Change Data Capture)是一种广泛应用于数据库和分布式系统的数据复制技术,其核心能力是实时捕获源系统中的数据变更事件(如表创建、删除,数据插入、更新、删除等),并将这些变更以日志流的形式实时传递到目标系统,实现源目数据的同步。
而在Milvus中, Milvus CDC能通过捕获并转发源集群的WAL(Write-AheadLog,预写日志)消息,将源集群的增量数据实时复制到目标集群,可以实现高效、低延迟的跨集群数据同步,是构建主备复制架构的核心组件。
其架构主要由三个核心部分组成:

-
源集群(SourceCluster /Primary):数据的唯一写入点,负责处理用户所有的DDL(数据定义语言)、DCL(数据控制语言)、DML(数据操纵语言)操作,这些操作会通过Streaming Nodes写入源集群的WAL日志中;
-
CDC Node:CDC组件的核心,负责与目标集群建立复制通道,通过Streaming Nodes提供的接口,持续消费源集群的WAL日志,并将日志内容转发到目标集群;
-
目标集群(Target Cluster):容灾备份节点,作为热备副本,接收来自CDC Node的WAL日志并写入自身的WAL,完成增量数据的复制,同时可承担读流量,实现读写分离。
其中,主集群是唯一的写入点(可读可写,所有的 DDL/DCL/DML 操作都必须指向主集群),备集群作为只读副本(只读,备集群作为热备副本,实时应用主集群同步过来的数据变更,并可用于分担业务的查询请求)。故障机制旨在保证主集群写入不中断的前提下,最大化查询服务的可用性。
此外,Milvus CDC针对跨集群数据同步场景还做了专项优化,使其具备以下关键特性,确保主备容灾方案的可靠性和稳定性:
-
实时性:基于消息流驱动,确保目标集群能及时获得源集群的增量数据,实现低延迟的实时同步。
-
一致性:确保消息的时序一致性与 Exactly Once 投递语义。
-
可靠性:CDC 支持断点续传,保证数据在系统故障或网络中断后不会丢失。
03
基于Milvus Operator,构建Milvus主备集群实操
本章节将详细介绍如何基于Milvus Operator,全新搭建主备集群并配置CDC主备复制,请注意以下前置注意事项,避免操作失误:
本文流程仅适用于全新构建集群的场景,若集群已有数据,请参考本系列下一篇文档(使用Milvus Backup升级主备集群);
Milvus版本需≥2.6.6,推荐使用2.6系列最新版本(CDC功能从2.6.6版本开始支持);
当前Milvus版本的CDC仅支持单副本部署,分布式部署功能将在后续版本中迭代支持;
CDC暂不支持同步Bulkinsert操作,开启CDC后将无法使用Bulkinsert能力,该限制将在后续版本中优化。
Step 1:升级 Operator 版本
升级 Milvus-Operator 到 v1.3.4(或以上)
helm repo add zilliztech-milvus-operator https://zilliztech.github.io/milvus-operator/
# "zilliztech-milvus-operator" has been added to your repositories
helm repo update zilliztech-milvus-operator
# Hang tight while we grab the latest from your chart repositories...
# ...Successfully got an update from the "zilliztech-milvus-operator" chart repository
# Update Complete. ⎈Happy Helming!⎈
helm -n milvus-operator upgrade milvus-operator zilliztech-milvus-operator/milvus-operator
# Release "milvus-operator" has been upgraded. Happy Helming!
# NAME: milvus-operator
# LAST DEPLOYED: Wed Dec 3 17:25:28 2025
# NAMESPACE: milvus-operator
# STATUS: deployed
# REVISION: 30
# TEST SUITE: None
# NOTES:
# Milvus Operator Is Starting, use `kubectl get -n milvus-operator deploy/milvus-operator` to check if its successfully installed
# Full Installation doc can be found in https://github.com/zilliztech/milvus-operator/blob/main/docs/installation/installation.md
# Quick start with `kubectl apply -f https://raw.githubusercontent.com/zilliztech/milvus-operator/main/config/samples/milvus_minimum.yaml`
# More samples can be found in https://github.com/zilliztech/milvus-operator/tree/main/config/samples
# CRD Documentation can be found in https://github.com/zilliztech/milvus-operator/tree/main/docs/CRD
# Administration Documentation can be found in https://github.com/zilliztech/milvus-operator/tree/main/docs/administration
查看pod状态,确认operator已升级
kubectl get pods -n milvus-operator
NAME READY STATUS RESTARTS AGE
milvus-operator-9fc99f88-h2hwz 1/1 Running 0 54s
Step 2:部署源集群
通过 milvus-operator 部署源集群,配置如下(其中包含了 CDC 组件):
# This is a sample to deploy a milvus cluster with cdc.
apiVersion: milvus.io/v1beta1
kind: Milvus
metadata:
name: source-cluster
namespace: milvus
labels:
app: milvus
spec:
mode: cluster
components:
image: milvusdb/milvus:v2.6.6 # Use version 2.6.6 or above, as CDC is available from 2.6.6 onwards
cdc:
replicas: 1 # Currently, CDC only supports 1 replica
dependencies:
msgStreamType: woodpecker
应用配置:
kubectl create namespace milvus
# namespace/milvus created
kubectl apply -f milvus_source_cluster.yaml
# milvus.milvus.io/source-cluster created
部署完成后,使用 kubectl 命令查看源集群 Pod 的运行状态:
kubectl get pods -n milvus
# 示例输出 (确保 source-cluster-milvus-cdc-xxx 处于 Running 状态):
# NAME READY STATUS RESTARTS AGE
# source-cluster-milvus-cdc-66d64747bd-sckxj 1/1 Running 0 2m42s
# source-cluster-milvus-datanode-85f9f56fd-qgbzq 1/1 Running 0 2m42s
# ...
Step 3:部署目标集群
通过 milvus-operator 部署被复制的目标集群,配置如下:
# This is a sample to deploy a milvus cluster with cdc.
apiVersion: milvus.io/v1beta1
kind: Milvus
metadata:
name: target-cluster
namespace: milvus
labels:
app: milvus
spec:
mode: cluster
components:
image: milvusdb/milvus:v2.6.6 # Use version 2.6.6 or above, as CDC is available from 2.6.6 onwards
dependencies:
msgStreamType: woodpecker
应用配置:
kubectl apply -f milvus_target_cluster.yaml
milvus.milvus.io/target-cluster created
部署完成后,使用 kubectl 命令查看源集群 Pod 的运行状态:
kubectl get pods -n milvus
# NAME READY STATUS RESTARTS AGE
# ...
# target-cluster-milvus-datanode-7ffc8cdb6b-xhzcd 1/1 Running 0 104m
# target-cluster-milvus-mixcoord-8649b87c98-btk7m 1/1 Running 0 104m
# ...
Step 4:创建复制关系
声明 source_cluster 和 target_cluster 的基本信息,包括 address,cluster ID 等:
source_cluster_addr = "http://10.98.124.90:19530" # address 示例,请替换为具体的 milvus server address
target_cluster_addr = "http://10.109.234.172:19530"
source_cluster_token = "root:Milvus"
target_cluster_token = "root:Milvus"
source_cluster_id = "source-cluster"
target_cluster_id = "target-cluster"
pchannel_num = 16
source_cluster_pchannels = []
target_cluster_pchannels = []
for i in range(pchannel_num):
source_cluster_pchannels.append(f"{source_cluster_id}-rootcoord-dml_{i}")
target_cluster_pchannels.append(f"{target_cluster_id}-rootcoord-dml_{i}")
创建 ReplicateConfiguration 对象,用于在 source_cluster 和 target_cluster 之间构建同步关系:
config = {
"clusters": [
{
"cluster_id": source_cluster_id,
"connection_param": {
"uri": source_cluster_addr,
"token": source_cluster_token
},
"pchannels": source_cluster_pchannels
},
{
"cluster_id": target_cluster_id,
"connection_param": {
"uri": target_cluster_addr,
"token": target_cluster_token
},
"pchannels": target_cluster_pchannels
}
],
"cross_cluster_topology": [
{
"source_cluster_id": source_cluster_id,
"target_cluster_id": target_cluster_id
}
]
}
对 source_cluster 和 target_cluster 调用 Milvus API 构建同步关系:
from pymilvus import MilvusClient
source_client = MilvusClient(uri=source_cluster_addr, token=source_cluster_token)
source_client.update_replicate_configuration(**config)
source_client.close()
target_client = MilvusClient(uri=target_cluster_addr, token=target_cluster_token)
target_client.update_replicate_configuration(**config)
target_client.close()
配置成功后,source_cluster 的数据增量变更将实时同步到 target_cluster。
Step 5:验证主备同步
-
在主集群创建 Collection 并插入数据
-
load 后执行 query/search 操作
-
连接备集群,执行 query/search 操作
-
若能查询到相同数据,即表示同步成功
相关操作参考: https://milvus.io/docs/quickstart.md
04
CDC 生产环境运维建议
为确保主备复制架构的稳定运行,结合生产环境实践,大家可以注意以下事项
监控复制延迟
Milvus CDC采用异步复制策略,备集群数据会略微落后于主集群。若延迟异常增大,可能存在网络拥塞、资源不足等问题,需及时排查解决;
备集群的容量管理
备集群需实时接收并存储主集群的增量数据,且需load与主集群相同的Collection,因此备集群的存储和计算资源应与主集群保持接近,避免资源不足导致同步失败;
利用备集群分担读流量
备集群支持只读操作,可将分析类负载、大Top K查询等非核心读请求迁移到备集群,分担主集群压力,提升整体系统的资源利用率。
05
FAQ
Q1: CDC 是否会影响查询性能?
不会明显影响正常读写操作。CDC 以异步方式消费消息日志,不占用主数据路径资源。
Q2: CDC 能否捕获历史数据?
CDC 默认仅捕获启用后发生的增量数据。如需导出历史数据,可使用 Milvus Backup 工具。
Q3:如何删除一个已建立的复制关系?
通过 Milvus API(UpdateReplicateConfiguration)将同步拓扑从配置中移除即可停止复制。
⚠️注意,删除复制关系后再次建立将破坏数据一致性,因此删除复制操作不可恢复。
06
尾声
未来,我们还将通过一系列文章介绍如何使用 Milvus Change Data Capture (CDC) 组件,构建主备复制架构,以应对可能发生的灾难性故障。
包括如下主题:
-
如何全新构建主备集群(本文)
-
如何使用 Milvus Backup 将已有数据的集群升级为主备集群
-
如何执行主备切换
下一篇,我们将介绍如何将使用 Milvus-Backup 将已有数据的集群升级为主备集群。