Configurar a Replicação CDC

Este guia mostra como implementar dois clusters Milvus autónomos com o Milvus Operator e configurar a replicação CDC de um cluster de origem para um cluster de destino.

Os exemplos usam:

  • source-cluster como o cluster primário.
  • target-cluster como o cluster de espera.
  • milvus como o espaço de nomes para os clusters Milvus.
  • milvus-operator como o espaço de nomes para o Milvus Operator.

Antes de começar, leia o CDC do Milvus para entender o modelo primário-em espera e as opções de failover.

Pré-requisitos

  • Milvus v2.6.16 ou posterior.
  • Milvus Operator v1.3.4 ou posterior.
  • Um cluster Kubernetes está disponível.
  • Os clusters de origem e destino podem se conectar uns aos outros pela rede.
  • Você tem credenciais de administrador para ambos os clusters do Milvus.
  • Você sabe a contagem de canais físicos para cada cluster.

Etapa 1: Atualizar o Milvus Operator

Adicione o repositório Helm do Milvus Operator:

helm repo add zilliztech-milvus-operator https://zilliztech.github.io/milvus-operator/

Atualizar o repositório:

helm repo update zilliztech-milvus-operator

Instalar ou atualizar o Milvus Operator:

helm -n milvus-operator upgrade --install milvus-operator \
  zilliztech-milvus-operator/milvus-operator \
  --create-namespace

Verificar se o pod do operador está em execução:

kubectl get pods -n milvus-operator

Exemplo de saída:

NAME                               READY   STATUS    RESTARTS   AGE
milvus-operator-6f7d8c9c7d-xm4tj   1/1     Running   0          54s

Etapa 2: Implantar o cluster de origem

Crie um arquivo chamado 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

Aplicar a configuração:

kubectl create namespace milvus
kubectl apply -f milvus_source_cluster.yaml

Verifique se os pods do cluster de origem estão em execução:

kubectl get pods -n milvus

Exemplo de saída:

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

Certifique-se de que o pod CDC, como source-cluster-milvus-cdc-..., esteja no estado Running.

Etapa 3: implantar o cluster de destino

Crie um arquivo chamado 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

O componente CDC também está ativado no cluster de destino. Ele fica inativo enquanto o destino é um standby, mas é necessário se o destino mais tarde se tornar o primário após a alternância.

Aplique a configuração:

kubectl apply -f milvus_target_cluster.yaml

Verifique se os pods do cluster de destino estão em execução:

kubectl get pods -n milvus | grep -E 'NAME|target-cluster'

Exemplo de saída:

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

Etapa 4: preparar informações do cluster

Obtenha os endereços de serviço Milvus para ambos os clusters:

kubectl get svc -n milvus | grep -E 'NAME|source-cluster|target-cluster'

Exemplo de saída:

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

Preparar dois tipos de endereços:

  • Os endereços do cluster são gravados na configuração de replicação e usados pelos componentes do CDC. Esses endereços devem ser acessíveis a partir dos pods do CDC.
  • Os endereços de cliente são utilizados apenas pelo seu cliente Python quando chama as APIs do Milvus. Se executar o cliente Python fora do cluster Kubernetes, exponha os serviços Milvus através do seu método de acesso normal, como um balanceador de carga, ingress ou port-forward.

Prepare as informações de conexão e as listas de pchannel para ambos os clusters:

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)
]

Substitua os endereços pelos endereços reais do serviço Milvus no seu ambiente. Não defina source_cluster_addr ou target_cluster_addr para um endereço de encaminhamento de porta local, a menos que os pods CDC também possam alcançar esse endereço. A lista pchannel deve corresponder à sua implantação do Milvus. Não copie os valores de exemplo sem verificar a configuração do cluster.

Etapa 5: criar a configuração de replicação

Crie uma configuração de replicação de source-cluster para 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,
        }
    ],
}

Etapa 6: Aplicar a configuração de replicação

Aplique a mesma configuração aos dois clusters:

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()

Para automação da produção, use clientes separados de curta duração para essa operação de plano de controle. Isso evita o compartilhamento do mesmo canal gRPC com o tráfego DML do aplicativo enquanto a função do cluster está sendo alterada.

Depois que a configuração é aplicada, as alterações gravadas em source-cluster são replicadas para target-cluster.

Etapa 7: verificar a replicação de dados

Para verificar se a replicação funciona:

  1. Conecte-se a source-cluster.
  2. Crie uma coleção.
  3. Insira dados na coleção.
  4. Carregue a coleção e execute uma consulta ou pesquisa em source-cluster.
  5. Ligue-se a target-cluster.
  6. Execute a mesma consulta ou pesquisa em target-cluster sem carregar manualmente a coleção no cluster em espera.
  7. Confirme se os dados esperados estão visíveis em ambos os clusters.

O cluster de destino é um cluster de espera nesta topologia. Não execute operações DDL ou DCL manuais, como load_collection, no cluster em espera. Essas operações devem ser executadas no cluster de origem e replicadas para o cluster de destino.

O código de verificação exato depende do seu esquema de recolha. Para obter um fluxo de trabalho básico de coleção do Milvus, consulte a documentação de início rápido do Milvus.

Atraso do CDC

O atraso do CDC é a janela de dados entre os clusters primário e em espera. É necessário monitorizá-lo continuamente após a configuração da replicação.

O atraso do CDC pode aumentar quando:

  • A taxa de gravação primária é alta.
  • A latência da rede ou a perda de pacotes aumenta entre os clusters.
  • O cluster em espera está sobrecarregado.
  • Os nós do CDC estão com provisionamento insuficiente.
  • Grandes operações DDL ou de importação estão em execução.

Use o atraso do CDC para orientar as decisões operacionais:

  • Se o atraso for baixo, a transição deve ser concluída mais rapidamente.
  • Se o atraso for alto, o failover pode perder mais dados.

É possível estimar o atraso do CDC com a seguinte consulta PromQL:

clamp_min(
  max by (channel_name) (
    milvus_wal_last_confirmed_time_tick
  )
  -
  min by (channel_name) (
    milvus_cdc_last_replicated_time_tick
  ),
  0
)

O resultado é em segundos. Para cada canal de origem, a consulta compara a última marca de tempo WAL confirmada com a última marca de tempo replicada pelo CDC. Se um primário replicar para vários clusters em espera, a expressão min by (channel_name) informa o progresso de replicação mais lento para esse canal.

Se o Prometheus fizer o scraping de vários clusters do Milvus, adicione filtros de rótulo que correspondam à sua implantação, como namespace ou app_kubernetes_io_instance, para evitar a mistura de métricas de diferentes clusters.

PERGUNTAS FREQUENTES

Preciso chamar update_replicate_configuration em ambos os clusters?

Sim. Aplique a mesma topologia a todos os clusters participantes. Se um cluster não for primário no momento da chamada, ele aguardará até que a topologia seja aplicada por meio do CDC.

Como devo escolher cluster_id?

Use uma ID estável e exclusiva para cada cluster. A ID também é usada em nomes de pchannel e referências de topologia de replicação.

Posso alterar os pchannels depois de a replicação estar configurada?

Pode atualizar a topologia, mas a lista de pchannels tem de corresponder à disposição do cluster. Trate as alterações de pchannel como uma operação avançada e verifique a replicação cuidadosamente depois disso.