从文件系统转移到 Cloud Storage

本页面介绍了如何在文件系统(即 本地或云端)和 Cloud Storage。

从文件系统到 Cloud Storage 的传输是基于代理的传输, 也就是说,您要在有权访问 来编排传输

配置权限

在创建转移作业之前,您必须为以下各项配置权限 实体:

用于创建转移作业的用户账号。这是 或登录 Google Cloud 控制台的账号 在向“gcloud”CLI 进行身份验证时指定。用户账号可以 是常规用户账号或用户代管式服务账号。
Google 管理的服务账号(也称为服务) 由 Storage Transfer Service 使用。该账号通常由 电子邮件地址,格式为 project-PROJECT_NUMBER@storage-transfer-service.iam.gserviceaccount.com.
提供 Google Cloud 的转移代理账号 权限。转移代理账号使用 安装它们的用户的凭据, 来进行身份验证

请参阅 基于代理的转移权限 了解相关说明。

将代理安装到代理池中

基于代理的传输使用软件代理来编排传输。这些代理 文件必须安装在能够访问 。

请勿包含个人身份信息,例如个人身份信息 (PII) 或安全数据。资源名称可能会传播到其他 Google Cloud 资源的名称,并且可能会向您项目之外的 Google 内部系统公开。
  1. 创建代理池。使用您的 用户账号 用户账号符号 执行此操作。
  2. 安装代理 添加到代理池中。使用您的转移代理账号 执行此操作。

我们建议先在来源代理池中添加 3 个代理。转移完成后 监控传输速度;你可以添加更多代理 池中。

我们建议每个代理使用一个虚拟机,每个虚拟机至少具有 4 个 CPU 和 8 GiB RAM。

转移选项

以下 Storage Transfer Service 功能适用于从 Cloud Storage

使用清单传输特定文件
您可以传递一系列文件,以供 Storage Transfer Service 进行处理。请参阅 转移特定文件或 对象
指定存储类别
您可以指定 Cloud Storage 存储类别,用于目标位置的数据 存储桶。请参阅 <ph type="x-smartling-placeholder"></ph> StorageClass 选项,或使用 --custom-storage-class 标志。

请注意,如果目标位置 存储桶已启用 Autoclass。如果 Autoclass 已启用,转移到存储桶的对象最初会 设置为 Standard Storage。

元数据保留

从文件系统传输文件时,Storage Transfer Service 可以 可以选择将某些属性保留为自定义元数据。如果这些文件 写入回文件系统后,Storage Transfer Service 可将 将保留的元数据还原为 POSIX 属性。

请参阅 POSIX 文件系统传输部分 元数据 保留,详细了解可以保留哪些元数据;以及 如何配置转移作业。

管理网络带宽
Storage Transfer Service 默认使用尽可能多的带宽 从文件系统中传输文件。您可以将带宽限制设置为 以防止传输影响其他网络流量。带宽限制 在代理池级别应用

请参阅管理 网络带宽

您的用户账号需要具备 Storage Transfer Admin 角色 (roles/storagetransfer.admin) 个要设置或更改的角色 带宽限制

日志记录
Storage Transfer Service 支持 Cloud Logging for Storage Transfer Service(推荐)以及 基于代理 转移日志

创建转移作业

请勿在转移作业名称中包含敏感信息,例如个人身份信息 (PII) 或安全数据。资源名称可能会传播到其他 Google Cloud 资源的名称,并且可能会向您项目之外的 Google 内部系统公开。

Storage Transfer Service 提供了多种接口,通过这些接口 。

Google Cloud 控制台

  1. 转到 Google Cloud 控制台中的 Storage Transfer Service 页面。

    转到 Storage Transfer Service

  2. 点击创建转移作业。 系统随即会显示创建转移作业页面。

  3. 选择 POSIX 文件系统作为来源。

  4. 选择 Cloud Storage 作为目标类型,然后点击下一步

  5. 您可以选择一个现有代理池,也可以选择创建代理池,然后按照说明创建一个新池。

  6. 指定文件系统目录的完全限定路径。

  7. 点击下一步

  8. 存储桶或文件夹字段中,输入目标存储桶以及(可选)文件夹名称,或点击浏览从当前项目的现有存储桶列表中选择一个存储桶。要创建新的存储桶,请点击 存储桶图标 创建新存储桶

  9. 点击下一步

  10. 选择日程安排选项。

  11. 点击下一步

  12. 为转移作业选择设置。

    • 说明字段中,输入转移作业的说明。最好输入有意义的说明 这样才能区分作业

    • 元数据选项下,使用默认选项。 或更新一个或多个值。如需了解详情,请参阅元数据保留

    • 何时覆盖下,选择以下选项之一:

      • 永不:Storage Transfer Service 会跳过从 与 目标。

      • 如果不同:如果同名的源文件具有不同的 ETag 或校验和值,则覆盖目标文件。

      • 始终:当源文件同名时,即使源文件相同,也始终覆盖目标文件。

    • 何时删除下,选择以下选项之一:

      • 永不:永不从源或目标中删除文件。

      • 在转移文件后从数据源删除文件:将文件转移到目标位置后,从数据源中删除文件。

      • 如果文件不在数据源中则从目标位置删除文件:如果目标 Cloud Storage 存储桶中的文件也不在数据源中,则从 Cloud Storage 存储桶中删除文件。

        此选项可确保目标 Cloud Storage 存储桶与您的数据源完全匹配。

    • 选择是否启用 Cloud Storage 中的日志记录和/或 在 Cloud Logging 中启用日志记录。请参阅 文件系统转移日志适用于 Storage Transfer Service 的 Cloud Logging

  13. 要创建转移作业,请点击创建

gcloud

在使用 gcloud 命令之前,请先安装 Google Cloud CLI

如需创建新的转移作业,请使用 gcloud transfer jobs create 命令。除非指定了时间表或 --do-not-run,否则创建新作业时会启动指定的转移作业。

gcloud transfer jobs create \
  posix:///SOURCE \
  gs://DESTINATION/ \
  --source-agent-pool=SOURCE_POOL_NAME

其中:

  • SOURCE 是 是文件系统的根目录前缀为 posix://,因此最终值 将包含 3 条正斜线。例如 posix:///tmp/data/

  • DESTINATION 是 Cloud Storage 存储桶的名称之一; (可选)后跟一个尾随斜杠(可选)。例如 gs://example-bucket/data/

  • --source-agent-pool 指定要用于此操作的来源代理池 。

其他选项包括:

  • --do-not-run 可阻止 Storage Transfer Service 在提交命令后运行作业。如需运行作业,请将其更新为 请添加时间表,或使用 jobs run 手动启动。

  • --manifest-file 指定 Cloud Storage 中 CSV 文件的路径,该文件包含要从来源转移的文件的列表。如需了解清单文件的格式,请参阅使用清单转移特定文件或对象

  • 作业信息:您可以指定 --name--description

  • 时间表:您可以指定 --schedule-starts--schedule-repeats-every--schedule-repeats-until--do-not-run

  • 转移选项:指定是否覆盖目标文件(--overwrite-when=differentalways),以及是否要在转移过程中或之后删除某些文件(--delete-from=destination-if-uniquesource-after-transfer);指定要保留的元数据值 (--preserve-metadata);(可选)为转移的对象设置存储类别 (--custom-storage-class)。

如需查看所有选项,请运行 gcloud transfer jobs create --help 或参阅 gcloud 参考文档。 请注意,并非所有选项都适用于基于代理的转移; 不受支持的选项的帮助文本中会注明这种效果。

REST

以下示例展示了如何通过 REST 使用 Storage Transfer Service API.

使用 Storage Transfer Service API 配置或编辑转移作业时,必须采用世界协调时间 (UTC)。如需详细了解如何指定转移作业的时间表,请参阅时间表

如需将文件从 POSIX 文件系统移到 Cloud Storage 存储桶,请执行以下操作: 使用 transferJobs.create 具有 posixDataSource

POST https://storagetransfer.googleapis.com/v1/transferJobs
{
 "name":"transferJobs/sample_transfer",
 "description": "My First Transfer",
 "status": "ENABLED",
 "projectId": "my_transfer_project_id",
 "schedule": {
     "scheduleStartDate": {
         "year": 2022,
         "month": 5,
         "day": 2
     },
     "startTimeOfDay": {
         "hours": 22,
         "minutes": 30,
         "seconds": 0,
         "nanos": 0
     }
     "scheduleEndDate": {
         "year": 2022,
         "month": 12,
         "day": 31
     },
     "repeatInterval": {
         "259200s"
     },
 },
 "transferSpec": {
     "posixDataSource": {
          "rootDirectory": "/bar/",
     },
     "sourceAgentPoolName": "my_example_pool",
     "gcsDataSink": {
          "bucketName": "destination_bucket"
          "path": "foo/bar/"
     },
  }
}

schedule 字段为可选字段;如果不包含,则必须使用 transferJobs.run 请求启动转移作业。

如需在创建作业后检查转移作业的状态,请使用 transferJobs.get

GET https://storagetransfer.googleapis.com/v1/transferJobs/sample_transfer?project_id=my_transfer_project_id

客户端库

以下示例展示了如何通过 Go、Java、Node.js 和 Python 以编程方式使用 Storage Transfer Service。

以编程方式配置或修改转移作业时,必须采用世界协调时间 (UTC)。如需详细了解如何指定转移作业的时间表,请参阅时间表

如需详细了解 Storage Transfer Service 客户端库,请参阅 Storage Transfer Service 客户端库使用入门

如需将文件从 POSIX 文件系统移动到 Cloud Storage 存储桶,请执行以下操作:

Go


import (
	"context"
	"fmt"
	"io"

	storagetransfer "cloud.google.com/go/storagetransfer/apiv1"
	"cloud.google.com/go/storagetransfer/apiv1/storagetransferpb"
)

func transferFromPosix(w io.Writer, projectID string, sourceAgentPoolName string, rootDirectory string, gcsSinkBucket string) (*storagetransferpb.TransferJob, error) {
	// Your project id
	// projectId := "myproject-id"

	// The agent pool associated with the POSIX data source. If not provided, defaults to the default agent
	// sourceAgentPoolName := "projects/my-project/agentPools/transfer_service_default"

	// The root directory path on the source filesystem
	// rootDirectory := "/directory/to/transfer/source"

	// The ID of the GCS bucket to transfer data to
	// gcsSinkBucket := "my-sink-bucket"

	ctx := context.Background()
	client, err := storagetransfer.NewClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("storagetransfer.NewClient: %w", err)
	}
	defer client.Close()

	req := &storagetransferpb.CreateTransferJobRequest{
		TransferJob: &storagetransferpb.TransferJob{
			ProjectId: projectID,
			TransferSpec: &storagetransferpb.TransferSpec{
				SourceAgentPoolName: sourceAgentPoolName,
				DataSource: &storagetransferpb.TransferSpec_PosixDataSource{
					PosixDataSource: &storagetransferpb.PosixFilesystem{RootDirectory: rootDirectory},
				},
				DataSink: &storagetransferpb.TransferSpec_GcsDataSink{
					GcsDataSink: &storagetransferpb.GcsData{BucketName: gcsSinkBucket},
				},
			},
			Status: storagetransferpb.TransferJob_ENABLED,
		},
	}

	resp, err := client.CreateTransferJob(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("failed to create transfer job: %w", err)
	}
	if _, err = client.RunTransferJob(ctx, &storagetransferpb.RunTransferJobRequest{
		ProjectId: projectID,
		JobName:   resp.Name,
	}); err != nil {
		return nil, fmt.Errorf("failed to run transfer job: %w", err)
	}
	fmt.Fprintf(w, "Created and ran transfer job from %v to %v with name %v", rootDirectory, gcsSinkBucket, resp.Name)
	return resp, nil
}

Java

import com.google.storagetransfer.v1.proto.StorageTransferServiceClient;
import com.google.storagetransfer.v1.proto.TransferProto;
import com.google.storagetransfer.v1.proto.TransferTypes.GcsData;
import com.google.storagetransfer.v1.proto.TransferTypes.PosixFilesystem;
import com.google.storagetransfer.v1.proto.TransferTypes.TransferJob;
import com.google.storagetransfer.v1.proto.TransferTypes.TransferSpec;
import java.io.IOException;

public class TransferFromPosix {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.

    // Your project id
    String projectId = "my-project-id";

    // The agent pool associated with the POSIX data source. If not provided, defaults to the
    // default agent
    String sourceAgentPoolName = "projects/my-project-id/agentPools/transfer_service_default";

    // The root directory path on the source filesystem
    String rootDirectory = "/directory/to/transfer/source";

    // The ID of the GCS bucket to transfer data to
    String gcsSinkBucket = "my-sink-bucket";

    transferFromPosix(projectId, sourceAgentPoolName, rootDirectory, gcsSinkBucket);
  }

  public static void transferFromPosix(
      String projectId, String sourceAgentPoolName, String rootDirectory, String gcsSinkBucket)
      throws IOException {
    TransferJob transferJob =
        TransferJob.newBuilder()
            .setProjectId(projectId)
            .setTransferSpec(
                TransferSpec.newBuilder()
                    .setSourceAgentPoolName(sourceAgentPoolName)
                    .setPosixDataSource(
                        PosixFilesystem.newBuilder().setRootDirectory(rootDirectory).build())
                    .setGcsDataSink(GcsData.newBuilder().setBucketName(gcsSinkBucket).build()))
            .setStatus(TransferJob.Status.ENABLED)
            .build();

    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources,
    // or use "try-with-close" statement to do this automatically.
    try (StorageTransferServiceClient storageTransfer = StorageTransferServiceClient.create()) {

      // Create the transfer job
      TransferJob response =
          storageTransfer.createTransferJob(
              TransferProto.CreateTransferJobRequest.newBuilder()
                  .setTransferJob(transferJob)
                  .build());

      System.out.println(
          "Created a transfer job from "
              + rootDirectory
              + " to "
              + gcsSinkBucket
              + " with "
              + "name "
              + response.getName());
    }
  }
}

Node.js


// Imports the Google Cloud client library
const {
  StorageTransferServiceClient,
} = require('@google-cloud/storage-transfer');

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// Your project id
// const projectId = 'my-project'

// The agent pool associated with the POSIX data source. Defaults to the default agent
// const sourceAgentPoolName = 'projects/my-project/agentPools/transfer_service_default'

// The root directory path on the source filesystem
// const rootDirectory = '/directory/to/transfer/source'

// The ID of the GCS bucket to transfer data to
// const gcsSinkBucket = 'my-sink-bucket'

// Creates a client
const client = new StorageTransferServiceClient();

/**
 * Creates a request to transfer from the local file system to the sink bucket
 */
async function transferDirectory() {
  const createRequest = {
    transferJob: {
      projectId,
      transferSpec: {
        sourceAgentPoolName,
        posixDataSource: {
          rootDirectory,
        },
        gcsDataSink: {bucketName: gcsSinkBucket},
      },
      status: 'ENABLED',
    },
  };

  // Runs the request and creates the job
  const [transferJob] = await client.createTransferJob(createRequest);

  const runRequest = {
    jobName: transferJob.name,
    projectId: projectId,
  };

  await client.runTransferJob(runRequest);

  console.log(
    `Created and ran a transfer job from '${rootDirectory}' to '${gcsSinkBucket}' with name ${transferJob.name}`
  );
}

transferDirectory();

Python

from google.cloud import storage_transfer


def transfer_from_posix_to_gcs(
    project_id: str,
    description: str,
    source_agent_pool_name: str,
    root_directory: str,
    sink_bucket: str,
):
    """Create a transfer from a POSIX file system to a GCS bucket."""

    client = storage_transfer.StorageTransferServiceClient()

    # The ID of the Google Cloud Platform Project that owns the job
    # project_id = 'my-project-id'

    # A useful description for your transfer job
    # description = 'My transfer job'

    # The agent pool associated with the POSIX data source.
    # Defaults to 'projects/{project_id}/agentPools/transfer_service_default'
    # source_agent_pool_name = 'projects/my-project/agentPools/my-agent'

    # The root directory path on the source filesystem
    # root_directory = '/directory/to/transfer/source'

    # Google Cloud Storage sink bucket name
    # sink_bucket = 'my-gcs-sink-bucket'

    transfer_job_request = storage_transfer.CreateTransferJobRequest(
        {
            "transfer_job": {
                "project_id": project_id,
                "description": description,
                "status": storage_transfer.TransferJob.Status.ENABLED,
                "transfer_spec": {
                    "source_agent_pool_name": source_agent_pool_name,
                    "posix_data_source": {
                        "root_directory": root_directory,
                    },
                    "gcs_data_sink": {"bucket_name": sink_bucket},
                },
            }
        }
    )

    result = client.create_transfer_job(transfer_job_request)
    print(f"Created transferJob: {result.name}")