设置 CDC 复制
本指南介绍如何使用 Milvus Operator 部署两个独立的 Milvus 集群,并配置 CDC 复制从源集群到目标集群。
示例使用
source-cluster作为主集群。target-cluster作为备用集群。milvus作为 Milvus 集群的命名空间。milvus-operator作为 Milvus Operator 的命名空间。
开始之前,请阅读 Milvus CDC 以了解主备模型和故障转移选项。
先决条件
- Milvus v2.6.16 或更高版本。
- Milvus Operator v1.3.4 或更高版本。
- Kubernetes 集群可用。
- 源集群和目标集群可以通过网络相互连接。
- 拥有两个 Milvus 集群的管理员凭证。
- 知道每个集群的物理通道数。
步骤 1:升级 Milvus Operator
添加 Milvus Operator Helm 仓库:
helm repo add zilliztech-milvus-operator https://zilliztech.github.io/milvus-operator/
更新版本库:
helm repo update zilliztech-milvus-operator
安装或升级 Milvus Operator:
helm -n milvus-operator upgrade --install milvus-operator \
zilliztech-milvus-operator/milvus-operator \
--create-namespace
检查运算符 pod 是否正在运行:
kubectl get pods -n milvus-operator
输出示例:
NAME READY STATUS RESTARTS AGE
milvus-operator-6f7d8c9c7d-xm4tj 1/1 Running 0 54s
步骤 2:部署源集群
创建名为 milvus_source_cluster.yaml 的文件:
apiVersion: milvus.io/v1beta1
kind: Milvus
metadata:
name: source-cluster
namespace: milvus
labels:
app: milvus
spec:
mode: standalone
components:
image: milvusdb/milvus:v2.6.16
cdc:
replicas: 1
dependencies:
msgStreamType: woodpecker
应用配置:
kubectl create namespace milvus
kubectl apply -f milvus_source_cluster.yaml
检查源集群 pod 是否正在运行:
kubectl get pods -n milvus
示例输出:
NAME READY STATUS RESTARTS AGE
source-cluster-etcd-0 1/1 Running 0 3m
source-cluster-minio-6d8f7d9b9f-9t7j2 1/1 Running 0 3m
source-cluster-milvus-standalone-7f8d9c8f6d-r2m5x 1/1 Running 0 2m
source-cluster-milvus-cdc-66d64747bd-sckxj 1/1 Running 0 2m
确保 CDC pod(如 source-cluster-milvus-cdc-...)处于 Running 状态。
第 3 步:部署目标集群
创建名为 milvus_target_cluster.yaml 的文件:
apiVersion: milvus.io/v1beta1
kind: Milvus
metadata:
name: target-cluster
namespace: milvus
labels:
app: milvus
spec:
mode: standalone
components:
image: milvusdb/milvus:v2.6.16
cdc:
replicas: 1
dependencies:
msgStreamType: woodpecker
CDC 组件也已在目标集群上启用。在目标集群为备用集群时,该组件处于空闲状态,但如果目标集群在切换后成为主集群,则需要该组件。
应用配置:
kubectl apply -f milvus_target_cluster.yaml
检查目标集群 pod 是否正在运行:
kubectl get pods -n milvus | grep -E 'NAME|target-cluster'
输出示例:
NAME READY STATUS RESTARTS AGE
target-cluster-etcd-0 1/1 Running 0 3m
target-cluster-minio-5f7c8d9b6f-k8s2q 1/1 Running 0 3m
target-cluster-milvus-standalone-66dc8d9f7f-5n6bp 1/1 Running 0 2m
target-cluster-milvus-cdc-7f8c9d6b8c-q4t9m 1/1 Running 0 2m
步骤 4:准备集群信息
获取两个集群的 Milvus 服务地址:
kubectl get svc -n milvus | grep -E 'NAME|source-cluster|target-cluster'
输出示例
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
source-cluster-milvus ClusterIP 10.98.124.90 <none> 19530/TCP,9091/TCP 8m
target-cluster-milvus ClusterIP 10.109.234.172 <none> 19530/TCP,9091/TCP 3m
准备两种地址:
- 集群地址被写入复制配置并由 CDC 组件使用。这些地址必须可以从 CDC pod 到达。
- 客户端地址仅在调用 Milvus API 时由 Python 客户端使用。如果在 Kubernetes 集群外运行 Python 客户端,请通过正常访问方法(如负载平衡器、入口或端口转发)公开 Milvus 服务。
为两个集群准备连接信息和 pchannel 列表:
source_cluster_addr = "http://source-cluster-milvus.milvus.svc.cluster.local:19530"
target_cluster_addr = "http://target-cluster-milvus.milvus.svc.cluster.local:19530"
source_client_addr = source_cluster_addr
target_client_addr = target_cluster_addr
# If your Python client runs outside the Kubernetes cluster, replace only
# source_client_addr and target_client_addr with externally reachable addresses.
# Keep source_cluster_addr and target_cluster_addr reachable from CDC pods.
# For example:
# source_client_addr = "http://127.0.0.1:19530"
# target_client_addr = "http://127.0.0.1:19531"
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 = [
f"{source_cluster_id}-rootcoord-dml_{i}"
for i in range(pchannel_num)
]
target_cluster_pchannels = [
f"{target_cluster_id}-rootcoord-dml_{i}"
for i in range(pchannel_num)
]
将地址替换为环境中实际的 Milvus 服务地址。不要将 source_cluster_addr 或 target_cluster_addr 设置为本地端口转发地址,除非 CDC pod 也能到达该地址。pchannel 列表必须与 Milvus 部署相匹配。请勿在未检查集群配置的情况下复制示例值。
第 5 步:创建复制配置
创建从 source-cluster 到 target-cluster 的复制配置:
replicate_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,
}
],
}
第 6 步:应用复制配置
对两个集群应用相同的配置:
from pymilvus import MilvusClient
source_client = MilvusClient(
uri=source_client_addr,
token=source_cluster_token,
)
target_client = MilvusClient(
uri=target_client_addr,
token=target_cluster_token,
)
try:
source_client.update_replicate_configuration(**replicate_config)
target_client.update_replicate_configuration(**replicate_config)
finally:
source_client.close()
target_client.close()
对于生产自动化,请使用单独的短命客户机进行此控制平面操作。这样可以避免在集群角色发生变化时与应用程序 DML 流量共享同一个 gRPChannel。
应用配置后,写入 source-cluster 的更改将复制到 target-cluster。
第 7 步:验证数据复制
验证复制是否有效:
- 连接到
source-cluster。 - 创建 Collection。
- 将数据插入 Collection。
- 加载 Collection 并在
source-cluster上运行查询或搜索。 - 连接到
target-cluster。 - 在
target-cluster上运行相同的查询或搜索,无需在备用集群上手动加载 Collection。 - 确认预期数据在两个集群上都可见。
目标集群是此拓扑中的备用集群。请勿在备用集群上运行手动 DDL 或 DCL 操作,如 load_collection。这些操作应在源集群上执行,并复制到目标集群。
确切的验证码取决于您的 Collection Schema。有关基本的 Milvus Collection 工作流程,请参阅 Milvus 快速入门文档。
CDC 滞后
CDC 滞后是指主集群和备用集群之间的数据窗口。配置复制后,应持续监控它。
CDC 滞后会在以下情况下增加:
- 主写入率高。
- 集群之间的网络延迟或数据包丢失增加。
- 备用集群超载。
- CDC 节点配置不足。
- 正在运行大型 DDL 或导入操作。
使用 CDC 滞后来指导运算符决策:
- 如果滞后较低,切换应更快完成。
- 如果滞后较高,故障切换可能会丢失更多数据。
可以使用以下 PromQL 查询估算 CDC 滞后:
clamp_min(
max by (channel_name) (
milvus_wal_last_confirmed_time_tick
)
-
min by (channel_name) (
milvus_cdc_last_replicated_time_tick
),
0
)
结果以秒为单位。对于每个源通道,该查询将最新确认的 WAL 时间戳与 CDC 复制的最后一个时间戳进行比较。如果主集群复制到多个备用集群,min by (channel_name) 表达式会报告该通道最慢的复制进度。
如果 Prometheus 扫描多个 Milvus 集群,请添加与部署相匹配的标签过滤器,如 namespace 或 app_kubernetes_io_instance,以避免混合来自不同集群的指标。
常见问题
我需要在两个集群上都调用 update_replicate_configuration 吗?
需要。对所有参与的集群应用相同的拓扑结构。如果一个集群在调用时不是主集群,它将等待,直到通过 CDC 应用拓扑。
如何选择 cluster_id?
为每个集群使用一个稳定、唯一的 ID。该 ID 也用于 pchannel 名称和复制拓扑引用。
配置复制后,能否更改 pchannel?
可以更新拓扑,但 pchannel 列表必须与集群布局相匹配。将 pchannel 更改视为高级运算符,并在更改后仔细验证复制。