管理永久性磁盘异步复制


本文档介绍如何启动和停止异步复制。

异步复制对于实现低 RPO 和低 RTO 的灾难恢复非常有用。如需详细了解异步复制,请参阅异步复制简介

限制

  • 主磁盘一次只能复制到一个辅助磁盘。
  • 复制停止后,您无法恢复到同一磁盘的复制操作。您必须创建新的辅助磁盘并重新开始复制。
  • 辅助磁盘在复制过程中无法挂接、删除或截取快照。
  • 如果您使用区域磁盘作为辅助磁盘,并且辅助磁盘的其中一个可用区发生服务中断故障,则从主磁盘复制到辅助磁盘的操作将失败。

准备工作

  • 如果需要跨多个磁盘校准复制,请创建一致性组
  • 创建主磁盘
  • 创建辅助磁盘
  • 如果您尚未设置身份验证,请进行设置。身份验证是通过其进行身份验证以访问 Google Cloud 服务和 API 的过程。如需从本地开发环境运行代码或示例,您可以通过选择以下选项之一向 Compute Engine 进行身份验证:

    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. After installing the Google Cloud CLI, initialize it by running the following command:

      gcloud init

      If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

    2. Set a default region and zone.
    3. Terraform

      如需在本地开发环境中使用本页面上的 Terraform 示例,请安装并初始化 gcloud CLI,然后使用您的用户凭证设置应用默认凭证。

      1. Install the Google Cloud CLI.

      2. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

      3. To initialize the gcloud CLI, run the following command:

        gcloud init
      4. 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.

      5. 如需了解详情,请参阅 Set up authentication for a local development environment

      REST

      如需在本地开发环境中使用本页面上的 REST API 示例,请使用您提供给 gcloud CLI 的凭据。

        After installing the Google Cloud CLI, initialize it by running the following command:

        gcloud init

        If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

      如需了解详情,请参阅 Google Cloud 身份验证文档中的使用 REST 时进行身份验证

      开始复制

      使用 Google Cloud 控制台、Google Cloud CLI、REST 或 Terraform 开始复制。

      控制台

      1. 在 Google Cloud 控制台中,前往异步复制页面。

        前往“异步复制”

      2. 点击您要开始向其复制数据的辅助磁盘的名称。

      3. 点击开始复制。此时会打开开始复制窗口。

      4. 点击开始复制

      gcloud

      使用 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
      

      请替换以下内容:

      • PRIMARY_DISK_NAME:主磁盘的名称。
      • PRIMARY_LOCATION_FLAG:主磁盘的位置标志。对于区域级磁盘,请使用 --region。对于可用区级磁盘,请使用 --zone
      • PRIMARY_LOCATION:主磁盘的区域或可用区。对于区域级磁盘,请使用区域。对于可用区磁盘,请使用可用区。
      • SECONDARY_DISK_NAME:辅助磁盘的名称。
      • SECONDARY_LOCATION_FLAG:辅助磁盘的位置标志。对于区域级磁盘,请使用 --secondary-disk-region。对于可用区级磁盘,请使用 --secondary-disk-zone
      • SECONDARY_LOCATION:辅助磁盘的区域或可用区。对于区域级磁盘,请使用区域。对于可用区磁盘,请使用可用区。
      • SECONDARY_PROJECT:包含辅助磁盘的项目。

      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

      使用以下方法之一开始复制:

      • 使用 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"
        }
        
      • 使用 regionDisks.startAsyncReplication 方法开始复制区域级磁盘:

        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"
        }
        

      请替换以下内容:

      • PRIMARY_DISK_PROJECT:包含主磁盘的项目。
      • PRIMARY_LOCATION:主磁盘的区域或可用区。对于区域级磁盘,请使用区域。对于可用区磁盘,请使用可用区。
      • PRIMARY_DISK_NAME:主磁盘的名称。
      • SECONDARY_DISK_PROJECT:包含辅助磁盘的项目。
      • SECONDARY_LOCATION_PARAMETER:辅助磁盘的位置参数。对于区域级磁盘,请使用 regions。对于可用区级磁盘,请使用 zones
      • SECONDARY_LOCATION:辅助磁盘的区域或可用区。对于区域级磁盘,请使用区域。对于可用区磁盘,请使用可用区。
      • SECONDARY_DISK_NAME:辅助磁盘的名称。

      Terraform

      如需开始在主磁盘与辅助磁盘之间进行复制,请使用 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
        }
      }

      如需了解如何应用或移除 Terraform 配置,请参阅基本 Terraform 命令

      停止复制

      您可以停止复制单个主磁盘或辅助磁盘,也可以停止复制一致性组中的所有磁盘。如果您停止复制一致性组中的单个磁盘,则该磁盘的复制时间将与一致性组中的其他磁盘不同步。

      故障切换和故障恢复场景中执行停止复制。如果您停止复制,则无法重新开始复制到同一辅助磁盘。如果想要重新开始复制,您必须创建一个新的辅助磁盘并重新开始复制。

      停止复制磁盘时,磁盘的复制状态会更改为 STOPPED。磁盘的复制对中另一个磁盘(相应的主磁盘或辅助磁盘)的复制状态稍后会更新为 STOPPED。如果要避免时间间隔并将另一个磁盘的复制状态立即更新为 STOPPED,则还必须手动停止另一个磁盘的复制。在两个磁盘上停止复制不会影响复制停止的时间,而只会影响磁盘的复制状态。

      停止单个磁盘的复制

      使用 Google Cloud 控制台、Google Cloud CLI 或 REST 停止单个磁盘的复制。

      控制台

      通过执行以下操作停止复制:

      1. 在 Google Cloud 控制台中,前往异步复制页面。

        前往“异步复制”

      2. 点击要停止复制的主磁盘或辅助磁盘的名称。系统随即会打开管理磁盘页面。

      3. 点击终止复制。系统会打开终止复制窗口。

      4. 点击终止复制

      gcloud

      使用 gcloud compute disks stop-async-replication 命令停止复制:

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

      请替换以下内容:

      • DISK_NAME:磁盘的名称。
      • LOCATION_FLAG:磁盘的位置标志。对于区域级磁盘,请使用 --region。对于可用区级磁盘,请使用 --zone
      • LOCATION:磁盘的区域或可用区。对于区域级磁盘,请使用区域。对于可用区磁盘,请使用可用区。

      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

      使用以下方法之一停止复制:

      • 使用 disks.stopAsyncReplication 方法停止复制可用区级磁盘:

        POST https://compute.googleapis.com/compute/v1/projects/PROJECT/zones/LOCATION/disks/DISK_NAME/stopAsyncReplication
        {
        }
        
      • 使用 regionDisks.stopAsyncReplication 方法停止复制区域级磁盘:

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

      请替换以下内容:

      • PROJECT:包含磁盘的项目。
      • DISK_NAME:磁盘的名称。
      • LOCATION:磁盘的可用区或区域。对于可用区磁盘,请使用可用区。对于区域级磁盘,请使用区域。

      Terraform

      如需停止在主磁盘和辅助磁盘上进行复制,请移除 compute_disk_async_replication 资源。

      停止一致性组复制

      使用Google Cloud 控制台、Google Cloud CLI 或 REST 停止一致性组中所有磁盘的复制。

      控制台

      如需停止一致性组中所有磁盘的复制操作,请执行以下操作:

      1. 在 Google Cloud 控制台中,前往异步复制页面。

        前往“异步复制”

      2. 点击一致性组标签页。

      3. 点击您要停止复制的一致性组的名称。系统随即会打开管理一致性组页面。

      4. 点击终止复制。系统会打开终止复制窗口。

      5. 点击终止复制

      gcloud

      使用 gcloud compute disks stop-group-async-replication 命令停止一致性组中所有磁盘的复制操作:

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

      请替换以下内容:

      • CONSISTENCY_GROUP:一致性组的网址。例如 projects/PROJECT/regions/REGION/resourcePolicies/CONSISTENCY_GROUP_NAME
      • LOCATION_FLAG:一致性组中的磁盘位置标志。对于区域级磁盘,请使用 --region。对于可用区级磁盘,请使用 --zone
      • LOCATION:磁盘的区域或可用区。对于区域级磁盘,请使用区域。对于可用区磁盘,请使用可用区。

      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

      使用以下方法之一停止一致性组中的所有磁盘的复制:

      • 使用 disks.stopGroupAsyncReplication 方法停止复制可用区级磁盘:

        POST https://compute.googleapis.com/compute/v1/projects/PROJECT/zones/LOCATION/disks/stopGroupAsyncReplication
        {
        "resourcePolicy": "CONSISTENCY_GROUP"
        }
        
      • 使用 regionDisks.stopGroupAsyncReplication 方法停止复制区域级磁盘:

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

      请替换以下内容:

      • DISK_NAME:磁盘的名称
      • LOCATION:磁盘的可用区或区域。对于可用区磁盘,请使用可用区。对于区域级磁盘,请使用区域。
      • CONSISTENCY_GROUP:一致性组的网址。例如 projects/PROJECT/regions/REGION/resourcePolicies/CONSISTENCY_GROUP_NAME

      后续步骤