ファイル システムから 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 権限を付与する転送エージェント アカウント。転送エージェント アカウントは、インストールしたユーザーの認証情報、またはユーザー管理のサービス アカウントの認証情報を使用して認証を行います。

手順については、エージェント ベースの転送の権限をご覧ください。

エージェント プールにエージェントをインストールする

エージェント ベースの転送では、ソフトウェア エージェントを使用して転送をオーケストレートします。これらのエージェントは、転送に関連するファイル システムにアクセスできるマシンにインストールする必要があります。

エージェント プール名やエージェント ID 接頭辞に、個人を特定できる情報(PII)やセキュリティ データなどの機密情報を含めないでください。リソース名は、他の Google Cloud リソースの名前に反映され、プロジェクト外部の Google 内部システムに公開される場合があります。
  1. エージェント プールの作成この操作には、ユーザー アカウント ユーザー アカウントのシンボル を使用します。
  2. エージェント プールにエージェントをインストールします。この操作には、転送エージェント アカウント を使用します。

転送元のエージェント プールでは、3 つのエージェントから始めることをおすすめします。転送が開始したら、転送速度をモニタリングします。転送中にプールにエージェントを追加できます。

エージェントごとに 1 つの VM を用意し、それぞれに少なくとも 4 個の CPU と 8 GiB の RAM を割り当てることをおすすめします。

転送オプション

ファイル システムから Cloud Storage への転送には、次の Storage Transfer Service 機能が使用できます。

マニフェストを使用して特定のファイルを転送する
Storage Transfer Service が処理するファイルのリストを渡すことができます。詳細については、マニフェストを使用して特定のファイルまたはオブジェクトを転送するをご覧ください。
ストレージ クラスを指定する
転送先バケットのデータに使用する Cloud Storage ストレージ クラスを指定できます。REST の詳細については、 StorageClass オプションを参照するか、Google Cloud CLI で --custom-storage-class フラグを使用します。

転送先バケットで Autoclass が有効になっている場合、ストレージ クラスの設定は無視されることに留意してください。Autoclass が有効になっている場合、バケットに転送されたオブジェクトは、最初は Standard Storage に設定されます。

メタデータの保持

ファイル システムからファイルを転送する際に、Storage Transfer Service は特定の属性をカスタム メタデータとして保持できます。これらのファイルが後でファイル システムに書き戻された場合、Storage Transfer Service は保存されたメタデータを POSIX 属性に変換できます。

保持できるメタデータの詳細と転送の構成方法については、メタデータの保持POSIX ファイル システム転送セクションをご覧ください。

ネットワーク帯域幅を管理する
Storage Transfer Service はデフォルトで、使用可能な帯域幅をすべて使用してファイル システムからファイルを転送します。帯域幅の上限を設定すると、転送が他のネットワーク トラフィックに影響するのを防ぐことができます。帯域幅の上限はエージェント プール レベルで適用されます。

詳細については、ネットワーク帯域幅を管理するをご覧ください。

帯域幅の上限を設定または変更するには、ユーザー アカウントに Storage Transfer 管理者roles/storagetransfer.admin)のロールが必要です。

ロギング
Storage Transfer Service は、 Storage Transfer Service 用 Cloud Logging (推奨)とエージェント ベースの転送ログをサポートしています。

転送を作成する

転送ジョブ名に、個人を特定できる情報(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. 転送ジョブの設定を選択します。

    • [説明] フィールドに、転送の説明を入力します。ジョブを区別できるように、意味のある一意の説明を入力することをおすすめします。

    • [メタデータのオプション] で、デフォルトのオプションを使用するか、1 つ以上の値を更新します。詳細については、メタデータの保持をご覧ください。

    • [上書きの条件] で、次のいずれかを選択します。

      • しない: 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=different または always)、転送中または転送後に特定のファイルを削除するかどうか(--delete-from=destination-if-unique または source-after-transfer)を指定します。保持するメタデータ値--preserve-metadata)を指定することや、転送されたオブジェクトにストレージ クラスを設定することもできます(--custom-storage-class)。

すべてのオプションを表示するには、gcloud transfer jobs create --help を実行するか、gcloud リファレンス ドキュメントをご覧ください。 なお、エージェント ベースの移行では、すべてのオプションがサポートされているわけではありません。サポートされていないオプションには、ヘルプテキストにその旨が記載されています。

REST

次の例は、REST API を介して Storage Transfer Service を使用する方法を示しています。

Storage Transfer Service API を使用して転送ジョブを構成または編集する場合は、時刻を UTC で設定してください。転送ジョブのスケジュールの指定方法については、スケジュールをご覧ください。

POSIX ファイル システムから Cloud Storage バケットにファイルを移動するには、posixDataSource を使用して transferJobs.create を使用します。

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