设置 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 操作符
添加 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 流量共享同一个 gRPC 通道。
应用配置后,写入source-cluster 的更改将复制到target-cluster 。
第 7 步:验证数据复制
验证复制是否有效:
- 连接到
source-cluster。 - 创建 Collections。
- 将数据插入 Collections。
- 加载 Collections 并在
source-cluster上运行查询或搜索。 - 连接到
target-cluster。 - 在
target-cluster上运行相同的查询或搜索,无需在备用群集上手动加载 Collections。 - 确认预期数据在两个群集上都可见。
目标群集是此拓扑中的备用群集。请勿在备用群集上运行手动 DDL 或 DCL 操作,如load_collection 。这些操作应在源群集上执行,并复制到目标群集。
确切的验证码取决于您的 Collections Schema。有关基本的 Milvus Collections 工作流程,请参阅 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 更改视为高级操作符,并在更改后仔细验证复制。