Faça a gestão da replicação assíncrona de discos persistentes


Este documento descreve como iniciar e parar a replicação assíncrona.

A replicação assíncrona é útil para a recuperação de desastres com RPO baixo e RTO baixo. Para saber mais sobre a replicação assíncrona, consulte o artigo Acerca da replicação assíncrona.

Limitações

  • Um disco principal só pode ser replicado para um disco secundário de cada vez.
  • Depois de a replicação parar, não pode retomá-la para o mesmo disco. Tem de criar um novo disco secundário e reiniciar a replicação.
  • Não é possível anexar, eliminar nem criar instantâneos de discos secundários enquanto estiverem em processo de replicação.
  • Se usar um disco regional como disco secundário e ocorrer uma indisponibilidade zonal numa das zonas do disco secundário, a replicação do disco principal para o disco secundário falha.

Antes de começar

  • Se precisar de alinhar a replicação em vários discos, crie um grupo de consistência.
  • Crie um disco principal.
  • Crie um disco secundário.
  • Se ainda não o tiver feito, configure a autenticação. A autenticação valida a sua identidade para aceder a Google Cloud serviços e APIs. Para executar código ou exemplos a partir de um ambiente de desenvolvimento local, pode autenticar-se no Compute Engine selecionando uma das seguintes opções:

    Select the tab for how you plan to use the samples on this page:

    Console

    When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.

    gcloud

    1. Instale a CLI Google Cloud. Após a instalação, inicialize a CLI gcloud executando o seguinte comando:

      gcloud init

      Se estiver a usar um fornecedor de identidade (IdP) externo, primeiro tem de iniciar sessão na CLI gcloud com a sua identidade federada.

    2. Set a default region and zone.

    Terraform

    Para usar os exemplos do Terraform nesta página num ambiente de desenvolvimento local, instale e inicialize a CLI gcloud e, em seguida, configure as credenciais predefinidas da aplicação com as suas credenciais de utilizador.

      Instale a CLI Google Cloud.

      Se estiver a usar um fornecedor de identidade (IdP) externo, primeiro tem de iniciar sessão na CLI gcloud com a sua identidade federada.

      If you're using a local shell, then create local authentication credentials for your user account:

      gcloud auth application-default login

      You don't need to do this if you're using Cloud Shell.

      If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.

    Para mais informações, consulte Set up authentication for a local development environment.

    REST

    Para usar os exemplos da API REST nesta página num ambiente de desenvolvimento local, usa as credenciais que fornece à CLI gcloud.

      Instale a CLI Google Cloud.

      Se estiver a usar um fornecedor de identidade (IdP) externo, primeiro tem de iniciar sessão na CLI gcloud com a sua identidade federada.

    Para mais informações, consulte o artigo Autenticar para usar REST na Google Cloud documentação de autenticação.

Inicie a replicação

Inicie a replicação através da Google Cloud consola, da Google Cloud CLI, da REST ou do Terraform.

Consola

  1. Na Google Cloud consola, aceda à página Replicação assíncrona.

    Aceda à replicação assíncrona

  2. Clique no nome do disco secundário para o qual quer iniciar a replicação.

  3. Clique em Iniciar replicação. É aberta a janela Iniciar replicação.

  4. Clique em Iniciar replicação.

gcloud

Inicie a replicação com o comando gcloud compute disks start-async-replication:

gcloud compute disks start-async-replication PRIMARY_DISK_NAME \
    --PRIMARY_LOCATION_FLAG=PRIMARY_LOCATION \
    --secondary-disk=SECONDARY_DISK_NAME \
    --SECONDARY_LOCATION_FLAG=SECONDARY_LOCATION \
    --secondary-disk-project=SECONDARY_PROJECT

Substitua o seguinte:

  • PRIMARY_DISK_NAME: o nome do disco principal.
  • PRIMARY_LOCATION_FLAG: o sinalizador de localização do disco principal. Para discos regionais, use --region. Para discos zonais, use --zone.
  • PRIMARY_LOCATION: a região ou a zona do disco principal. Para discos regionais, use a região. Para discos zonais, use a zona.
  • SECONDARY_DISK_NAME: o nome do disco secundário.
  • SECONDARY_LOCATION_FLAG: o sinalizador de localização do disco secundário. Para discos regionais, use --secondary-disk-region. Para discos zonais, use --secondary-disk-zone.
  • SECONDARY_LOCATION: a região ou a zona do disco secundário. Para discos regionais, use a região. Para discos zonais, use a zona.
  • SECONDARY_PROJECT: o projeto que contém o disco secundário.

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
)

// startReplication starts disk replication in a project for a given zone.
func startReplication(
	w io.Writer,
	projectID, zone, diskName, primaryDiskName, primaryZone string,
) error {
	// projectID := "your_project_id"
	// zone := "europe-west4-b"
	// diskName := "your_disk_name"
	// primaryDiskName := "your_disk_name2"
	// primaryZone := "europe-west2-b"

	ctx := context.Background()
	disksClient, err := compute.NewDisksRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewDisksRESTClient: %w", err)
	}
	defer disksClient.Close()

	secondaryFullDiskName := fmt.Sprintf("projects/%s/zones/%s/disks/%s", projectID, zone, diskName)

	req := &computepb.StartAsyncReplicationDiskRequest{
		Project: projectID,
		Zone:    primaryZone,
		Disk:    primaryDiskName,
		DisksStartAsyncReplicationRequestResource: &computepb.DisksStartAsyncReplicationRequest{
			AsyncSecondaryDisk: &secondaryFullDiskName,
		},
	}

	op, err := disksClient.StartAsyncReplication(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create disk: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Replication started\n")

	return nil
}

Java

import com.google.cloud.compute.v1.DisksClient;
import com.google.cloud.compute.v1.DisksStartAsyncReplicationRequest;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import com.google.cloud.compute.v1.StartAsyncReplicationDiskRequest;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class StartZonalDiskReplication {

  public static void main(String[] args)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // The project that contains the primary disk.
    String projectId = "YOUR_PROJECT_ID";
    // Name of the primary disk.
    String primaryDiskName = "PRIMARY_DISK_NAME";
    // Name of the secondary disk.
    String secondaryDiskName = "SECONDARY_DISK_NAME";
    // Name of the zone in which your primary disk is located.
    // Learn more about zones and regions:
    // https://cloud.google.com/compute/docs/disks/async-pd/about#supported_region_pairs
    String primaryDiskLocation = "us-central1-a";
    // Name of the zone in which your secondary disk is located.
    String secondaryDiskLocation = "us-east1-b";

    startZonalDiskAsyncReplication(projectId, primaryDiskName, primaryDiskLocation,
            secondaryDiskName, secondaryDiskLocation);
  }

  // Starts asynchronous replication for the specified zonal disk.
  public static Status startZonalDiskAsyncReplication(String projectId, String primaryDiskName,
      String primaryDiskLocation, String secondaryDiskName, String secondaryDiskLocation)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    String secondaryDiskPath = String.format("projects/%s/zones/%s/disks/%s",
            projectId, secondaryDiskLocation, secondaryDiskName);
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (DisksClient disksClient = DisksClient.create()) {
      DisksStartAsyncReplicationRequest diskRequest =
              DisksStartAsyncReplicationRequest.newBuilder()
                      .setAsyncSecondaryDisk(secondaryDiskPath)
                      .build();

      StartAsyncReplicationDiskRequest request =
              StartAsyncReplicationDiskRequest.newBuilder()
                      .setDisk(primaryDiskName)
                      .setDisksStartAsyncReplicationRequestResource(diskRequest)
                      .setProject(projectId)
                      .setZone(primaryDiskLocation)
                      .build();
      Operation response = disksClient.startAsyncReplicationAsync(request).get(1, TimeUnit.MINUTES);

      if (response.hasError()) {
        throw new Error("Error starting replication! " + response.getError());
      }
      return response.getStatus();
    }
  }
}

Node.js

// Import the Compute library
const computeLib = require('@google-cloud/compute');
const compute = computeLib.protos.google.cloud.compute.v1;

// Instantiate a diskClient
const disksClient = new computeLib.DisksClient();
// Instantiate a zoneOperationsClient
const zoneOperationsClient = new computeLib.ZoneOperationsClient();

/**
 * TODO(developer): Update/uncomment these variables before running the sample.
 */
// The project of the secondary disk.
const secondaryProjectId = await disksClient.getProjectId();

// The zone of the secondary disk.
// secondaryLocation = 'us-central1-a';

// The name of the secondary disk.
// secondaryDiskName = 'secondary-disk-name';

// The project of the primary disk.
const primaryProjectId = await disksClient.getProjectId();

// The zone of the primary disk.
// primaryLocation = 'us-central1-a';

// The name of the primary disk.
// primaryDiskName = 'primary-disk-name';

// Start replication
async function callStartReplication() {
  const [response] = await disksClient.startAsyncReplication({
    project: secondaryProjectId,
    zone: primaryLocation,
    disk: primaryDiskName,
    disksStartAsyncReplicationRequestResource:
      new compute.DisksStartAsyncReplicationRequest({
        asyncSecondaryDisk: `projects/${primaryProjectId}/zones/${secondaryLocation}/disks/${secondaryDiskName}`,
      }),
  });

  let operation = response.latestResponse;

  // Wait for the operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await zoneOperationsClient.wait({
      operation: operation.name,
      project: secondaryProjectId,
      zone: operation.zone.split('/').pop(),
    });
  }

  console.log(
    `Data replication from primary disk: ${primaryDiskName} to secondary disk: ${secondaryDiskName} started.`
  );
}

await callStartReplication();

Python

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def start_disk_replication(
    project_id: str,
    primary_disk_location: str,
    primary_disk_name: str,
    secondary_disk_location: str,
    secondary_disk_name: str,
) -> bool:
    """Starts the asynchronous replication of a primary disk to a secondary disk.
    Args:
        project_id (str): The ID of the Google Cloud project.
        primary_disk_location (str): The location of the primary disk, either a zone or a region.
        primary_disk_name (str): The name of the primary disk.
        secondary_disk_location (str): The location of the secondary disk, either a zone or a region.
        secondary_disk_name (str): The name of the secondary disk.
    Returns:
        bool: True if the replication was successfully started.
    """
    # Check if the primary disk location is a region or a zone.
    if primary_disk_location[-1].isdigit():
        region_client = compute_v1.RegionDisksClient()
        request_resource = compute_v1.RegionDisksStartAsyncReplicationRequest(
            async_secondary_disk=f"projects/{project_id}/regions/{secondary_disk_location}/disks/{secondary_disk_name}"
        )
        operation = region_client.start_async_replication(
            project=project_id,
            region=primary_disk_location,
            disk=primary_disk_name,
            region_disks_start_async_replication_request_resource=request_resource,
        )
    else:
        client = compute_v1.DisksClient()
        request_resource = compute_v1.DisksStartAsyncReplicationRequest(
            async_secondary_disk=f"zones/{secondary_disk_location}/disks/{secondary_disk_name}"
        )
        operation = client.start_async_replication(
            project=project_id,
            zone=primary_disk_location,
            disk=primary_disk_name,
            disks_start_async_replication_request_resource=request_resource,
        )
    wait_for_extended_operation(operation, verbose_name="replication operation")
    print(f"Replication for disk {primary_disk_name} started.")
    return True

REST

Inicie a replicação através de um dos seguintes métodos:

  • Inicie a replicação de discos zonais através do método disks.startAsyncReplication:

    POST https://compute.googleapis.com/compute/v1/projects/PRIMARY_DISK_PROJECT/zones/PRIMARY_LOCATION/disks/PRIMARY_DISK_NAME/startAsyncReplication
    
    {
    "asyncSecondaryDisk": "projects/SECONDARY_DISK_PROJECT/SECONDARY_LOCATION_PARAMETER/SECONDARY_LOCATION/disks/SECONDARY_DISK_NAME"
    }
    
  • Inicie a replicação para discos regionais através do regionDisks.startAsyncReplication método:

    POST https://compute.googleapis.com/compute/v1/projects/PRIMARY_DISK_PROJECT/regions/PRIMARY_LOCATION/regionDisks/PRIMARY_DISK_NAME/startAsyncReplication
    
    {
    "asyncSecondaryDisk": "projects/SECONDARY_DISK_PROJECT/SECONDARY_LOCATION_PARAMETER/SECONDARY_LOCATION/disks/SECONDARY_DISK_NAME"
    }
    

Substitua o seguinte:

  • PRIMARY_DISK_PROJECT: o projeto que contém o disco principal.
  • PRIMARY_LOCATION: a região ou a zona do disco principal. Para discos regionais, use a região. Para discos zonais, use a zona.
  • PRIMARY_DISK_NAME: o nome do disco principal.
  • SECONDARY_DISK_PROJECT: o projeto que contém o disco secundário.
  • SECONDARY_LOCATION_PARAMETER: o parâmetro de localização para o disco secundário. Para discos regionais, use regions. Para discos zonais, use zones.
  • SECONDARY_LOCATION: a região ou a zona do disco secundário. Para discos regionais, use a região. Para discos zonais, use a zona.
  • SECONDARY_DISK_NAME: o nome do disco secundário.

Terraform

Para iniciar a replicação entre discos primários e secundários, use o recurso compute_disk_async_replication.

resource "google_compute_disk_async_replication" "default" {
  primary_disk = google_compute_disk.primary_disk.id
  secondary_disk {
    disk = google_compute_disk.secondary_disk.id
  }
}

Para saber como aplicar ou remover uma configuração do Terraform, consulte os comandos básicos do Terraform.

Pare a replicação

Pode parar a replicação de um único disco principal ou secundário, ou de todos os discos num grupo de consistência. Se parar a replicação de um único disco num grupo de consistência, o tempo de replicação desse disco fica dessincronizado com os outros discos no grupo de consistência.

A interrupção da replicação é realizada em cenários de failover e failback. Se parar a replicação, não pode reiniciá-la para o mesmo disco secundário. Se quiser reiniciar a replicação, tem de criar um novo disco secundário e começar de novo.

Quando para a replicação num disco, o estado de replicação do disco muda para STOPPED. O estado de replicação do outro disco no par de replicação do disco (o disco principal ou secundário correspondente) é atualizado para STOPPED mais tarde. Se quiser evitar o intervalo de tempo e atualizar o estado de replicação do outro disco para STOPPED imediatamente, também tem de parar manualmente a replicação no outro disco. A paragem da replicação em ambos os discos não afeta a hora em que a replicação é interrompida, apenas afeta os estados de replicação dos discos.

Pare a replicação de um único disco

Pare a replicação de um único disco através da Google Cloud consola, da Google Cloud CLI ou do REST.

Consola

Pare a replicação fazendo o seguinte:

  1. Na Google Cloud consola, aceda à página Replicação assíncrona.

    Aceda à replicação assíncrona

  2. Clique no nome do disco principal ou secundário para o qual quer parar a replicação. É aberta a página Gerir disco.

  3. Clique em Terminar replicação. A janela Terminar replicação é aberta.

  4. Clique em Terminar replicação.

gcloud

Pare a replicação com o comando gcloud compute disks stop-async-replication:

gcloud compute disks stop-async-replication DISK_NAME \
    --LOCATION_FLAG=LOCATION

Substitua o seguinte:

  • DISK_NAME: o nome do disco.
  • LOCATION_FLAG: o indicador de localização do disco. Para um disco regional, use --region. Para um disco zonal, use --zone.
  • LOCATION: a região ou a zona do disco. Para discos regionais, use a região. Para discos zonais, use a zona.

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
)

// stopReplication stops primary disk replication in a project for a given zone.
func stopReplication(
	w io.Writer,
	projectID, primaryDiskName, primaryZone string,
) error {
	// projectID := "your_project_id"
	// primaryDiskName := "your_disk_name2"
	// primaryZone := "europe-west2-b"

	ctx := context.Background()
	disksClient, err := compute.NewDisksRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewDisksRESTClient: %w", err)
	}
	defer disksClient.Close()

	req := &computepb.StopAsyncReplicationDiskRequest{
		Project: projectID,
		Zone:    primaryZone,
		Disk:    primaryDiskName,
	}

	op, err := disksClient.StopAsyncReplication(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create disk: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Replication stopped\n")

	return nil
}

Java

import com.google.cloud.compute.v1.DisksClient;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import com.google.cloud.compute.v1.StopAsyncReplicationDiskRequest;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class StopZonalDiskReplication {

  public static void main(String[] args)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // The project that contains the primary disk.
    String projectId = "YOUR_PROJECT_ID";
    // Name of the region or zone in which your secondary disk is located.
    String secondaryDiskLocation = "us-east1-b";
    // Name of the secondary disk.
    String secondaryDiskName = "SECONDARY_DISK_NAME";

    stopZonalDiskAsyncReplication(projectId, secondaryDiskLocation, secondaryDiskName);
  }

  // Stops asynchronous replication for the specified disk.
  public static Status stopZonalDiskAsyncReplication(
          String project, String secondaryDiskLocation, String secondaryDiskName)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (DisksClient disksClient = DisksClient.create()) {
      StopAsyncReplicationDiskRequest stopReplicationDiskRequest =
              StopAsyncReplicationDiskRequest.newBuilder()
                      .setProject(project)
                      .setDisk(secondaryDiskName)
                      .setZone(secondaryDiskLocation)
                      .build();
      Operation response = disksClient.stopAsyncReplicationAsync(stopReplicationDiskRequest)
              .get(1, TimeUnit.MINUTES);

      if (response.hasError()) {
        throw new Error("Error stopping replication! " + response.getError());
      }
      return response.getStatus();
    }
  }
}

Node.js

// Import the Compute library
const computeLib = require('@google-cloud/compute');

// Instantiate a diskClient
const disksClient = new computeLib.DisksClient();
// Instantiate a zoneOperationsClient
const zoneOperationsClient = new computeLib.ZoneOperationsClient();

/**
 * TODO(developer): Update/uncomment these variables before running the sample.
 */
// The project that contains the primary disk.
const primaryProjectId = await disksClient.getProjectId();

// The zone of the primary disk.
// primaryLocation = 'us-central1-a';

// The name of the primary disk.
// primaryDiskName = 'primary-disk-name';

// Stop replication
async function callStopReplication() {
  const [response] = await disksClient.stopAsyncReplication({
    project: primaryProjectId,
    zone: primaryLocation,
    disk: primaryDiskName,
  });

  let operation = response.latestResponse;

  // Wait for the operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await zoneOperationsClient.wait({
      operation: operation.name,
      project: primaryProjectId,
      zone: operation.zone.split('/').pop(),
    });
  }

  console.log(`Replication for primary disk: ${primaryDiskName} stopped.`);
}

await callStopReplication();

Python

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def stop_disk_replication(
    project_id: str, primary_disk_location: str, primary_disk_name: str
) -> bool:
    """
    Stops the asynchronous replication of a disk.
    Args:
        project_id (str): The ID of the Google Cloud project.
        primary_disk_location (str): The location of the primary disk, either a zone or a region.
        primary_disk_name (str): The name of the primary disk.
    Returns:
        bool: True if the replication was successfully stopped.
    """
    # Check if the primary disk is in a region or a zone
    if primary_disk_location[-1].isdigit():
        region_client = compute_v1.RegionDisksClient()
        operation = region_client.stop_async_replication(
            project=project_id, region=primary_disk_location, disk=primary_disk_name
        )
    else:
        zone_client = compute_v1.DisksClient()
        operation = zone_client.stop_async_replication(
            project=project_id, zone=primary_disk_location, disk=primary_disk_name
        )

    wait_for_extended_operation(operation, verbose_name="replication operation")
    print(f"Replication for disk {primary_disk_name} stopped.")
    return True

REST

Pare a replicação através de um dos seguintes métodos:

  • Pare a replicação de discos zonais através do método disks.stopAsyncReplication:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT/zones/LOCATION/disks/DISK_NAME/stopAsyncReplication
    {
    }
    
  • Pare a replicação de discos regionais através do método regionDisks.stopAsyncReplication:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT/regions/LOCATION/regionDisks/DISK_NAME/stopAsyncReplication
    {
    }
    

Substitua o seguinte:

  • PROJECT: o projeto que contém o disco.
  • DISK_NAME: o nome do disco.
  • LOCATION: a zona ou a região do disco. Para discos zonais, use a zona. Para discos regionais, use a região.

Terraform

Para parar a replicação nos discos principal e secundário, remova o recurso compute_disk_async_replication.

Pare a replicação de um grupo de consistência

Pare a replicação de todos os discos num grupo de consistência através da Google Cloud consola, da Google Cloud CLI ou do REST.

Consola

Pare a replicação de todos os discos num grupo de consistência fazendo o seguinte:

  1. Na Google Cloud consola, aceda à página Replicação assíncrona.

    Aceda à replicação assíncrona

  2. Clique no separador Grupos de consistência.

  3. Clique no nome do grupo de consistência para o qual quer parar a replicação. É aberta a página Gerir grupo de consistência.

  4. Clique em Terminar replicação. A janela Terminar replicação é aberta.

  5. Clique em Terminar replicação.

gcloud

Pare a replicação de todos os discos num grupo de consistência através do comando gcloud compute disks stop-group-async-replication:

gcloud compute disks stop-group-async-replication CONSISTENCY_GROUP \
--LOCATION_FLAG=LOCATION

Substitua o seguinte:

  • CONSISTENCY_GROUP: o URL do grupo de consistência. Por exemplo, projects/PROJECT/regions/REGION/resourcePolicies/CONSISTENCY_GROUP_NAME.
  • LOCATION_FLAG: o sinalizador de localização para os discos no grupo de consistência. Para discos regionais, use --region. Para discos zonais, use --zone.
  • LOCATION: a região ou a zona do disco. Para discos regionais, use a região. Para discos zonais, use a zona.

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
	"google.golang.org/protobuf/proto"
)

// stopReplicationConsistencyGroup stop replication for a consistency group for a project in a given region.
func stopReplicationConsistencyGroup(w io.Writer, projectID, region, groupName string) error {
	// projectID := "your_project_id"
	// region := "europe-west4"
	// groupName := "your_group_name"

	ctx := context.Background()
	disksClient, err := compute.NewRegionDisksRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewResourcePoliciesRESTClient: %w", err)
	}
	defer disksClient.Close()

	consistencyGroupUrl := fmt.Sprintf("projects/%s/regions/%s/resourcePolicies/%s", projectID, region, groupName)

	req := &computepb.StopGroupAsyncReplicationRegionDiskRequest{
		Project: projectID,
		DisksStopGroupAsyncReplicationResourceResource: &computepb.DisksStopGroupAsyncReplicationResource{
			ResourcePolicy: proto.String(consistencyGroupUrl),
		},
		Region: region,
	}

	op, err := disksClient.StopGroupAsyncReplication(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to stop replication: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Group stopped replicating\n")

	return nil
}

Java

import com.google.cloud.compute.v1.DisksClient;
import com.google.cloud.compute.v1.DisksStopGroupAsyncReplicationResource;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import com.google.cloud.compute.v1.StopGroupAsyncReplicationDiskRequest;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class StopZonalDiskReplicationConsistencyGroup {
  public static void main(String[] args)
          throws IOException, InterruptedException, ExecutionException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project that contains the disk.
    String project = "YOUR_PROJECT_ID";
    // Zone of the disk.
    String zone = "us-central1-a";
    // Name of the consistency group.
    String consistencyGroupName = "CONSISTENCY_GROUP";

    stopZonalDiskReplicationConsistencyGroup(project, zone, consistencyGroupName);
  }

  // Stops replication of a consistency group for a project in a given zone.
  public static Status stopZonalDiskReplicationConsistencyGroup(
          String project, String zone, String consistencyGroupName)
          throws IOException, InterruptedException, ExecutionException, TimeoutException {
    String region = zone.substring(0, zone.lastIndexOf('-'));

    String resourcePolicy = String.format("projects/%s/regions/%s/resourcePolicies/%s",
            project, region, consistencyGroupName);
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (DisksClient disksClient = DisksClient.create()) {
      StopGroupAsyncReplicationDiskRequest request =
              StopGroupAsyncReplicationDiskRequest.newBuilder()
                      .setProject(project)
                      .setZone(zone)
                      .setDisksStopGroupAsyncReplicationResourceResource(
                              DisksStopGroupAsyncReplicationResource.newBuilder()
                                      .setResourcePolicy(resourcePolicy).build())
                      .build();
      Operation response = disksClient.stopGroupAsyncReplicationAsync(request)
              .get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        throw new Error("Error stopping disk replication! " + response.getError());
      }
      return response.getStatus();
    }
  }
}

Node.js

// Import the Compute library
const computeLib = require('@google-cloud/compute');
const compute = computeLib.protos.google.cloud.compute.v1;

// If disks are regional- use RegionDisksClient and RegionOperationsClient.
// TODO(developer): Uncomment disksClient and zoneOperationsClient before running the sample.
// Instantiate a disksClient
// disksClient = new computeLib.DisksClient();
// Instantiate a zoneOperationsClient
// zoneOperationsClient = new computeLib.ZoneOperationsClient();

/**
 * TODO(developer): Update/uncomment these variables before running the sample.
 */
// The project that contains the consistency group.
const projectId = await disksClient.getProjectId();

// If you use RegionDisksClient- define region, if DisksClient- define zone.
// The zone or region of the disks.
const disksLocation = 'europe-central2-a';

// The name of the consistency group.
const consistencyGroupName = 'consistency-group-1';

// The region of the consistency group.
const consistencyGroupLocation = 'europe-central2';

async function callStopReplication() {
  const [response] = await disksClient.stopGroupAsyncReplication({
    project: projectId,
    // If you use RegionDisksClient, pass region as an argument instead of zone.
    zone: disksLocation,
    disksStopGroupAsyncReplicationResourceResource:
      new compute.DisksStopGroupAsyncReplicationResource({
        resourcePolicy: [
          `https://www.googleapis.com/compute/v1/projects/${projectId}/regions/${consistencyGroupLocation}/resourcePolicies/${consistencyGroupName}`,
        ],
      }),
  });

  let operation = response.latestResponse;

  // Wait for the operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await zoneOperationsClient.wait({
      operation: operation.name,
      project: projectId,
      // If you use RegionDisksClient, pass region as an argument instead of zone.
      zone: operation.zone.split('/').pop(),
    });
  }

  const message = `Replication stopped for consistency group: ${consistencyGroupName}.`;
  console.log(message);
  return message;
}

return await callStopReplication();

Python

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def stop_replication_consistency_group(project_id, location, consistency_group_name):
    """
    Stops the asynchronous replication for a consistency group.
    Args:
        project_id (str): The ID of the Google Cloud project.
        location (str): The region where the consistency group is located.
        consistency_group_id (str): The ID of the consistency group.
    Returns:
        bool: True if the replication was successfully stopped.
    """
    consistency_group = compute_v1.DisksStopGroupAsyncReplicationResource(
        resource_policy=f"regions/{location}/resourcePolicies/{consistency_group_name}"
    )
    region_client = compute_v1.RegionDisksClient()
    operation = region_client.stop_group_async_replication(
        project=project_id,
        region=location,
        disks_stop_group_async_replication_resource_resource=consistency_group,
    )
    wait_for_extended_operation(operation, "Stopping replication for consistency group")

    return True

REST

Pare a replicação de todos os discos num grupo de consistência através de um dos seguintes métodos:

  • Pare a replicação de discos zonais através do método disks.stopGroupAsyncReplication:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT/zones/LOCATION/disks/stopGroupAsyncReplication
    {
    "resourcePolicy": "CONSISTENCY_GROUP"
    }
    
  • Pare a replicação de discos regionais através do método regionDisks.stopGroupAsyncReplication:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT/regions/LOCATION/regionDisks/DISK_NAME/stopAsyncReplication
    {
    "resourcePolicy": "CONSISTENCY_GROUP"
    }
    

Substitua o seguinte:

  • DISK_NAME: o nome do disco
  • LOCATION: a zona ou a região do disco. Para discos zonais, use a zona. Para discos regionais, use a região.
  • CONSISTENCY_GROUP: o URL do grupo de consistência. Por exemplo, projects/PROJECT/regions/REGION/resourcePolicies/CONSISTENCY_GROUP_NAME.

O que se segue?