ファイル システムから Cloud Storage に転送する

このページでは、ファイル システム(オンプレミスまたはクラウド)と Cloud Storage の間で転送ジョブを作成する方法について説明します。

ファイル システムから Cloud Storage への転送はエージェント ベースの転送です。つまり、ファイル システムにアクセスできるマシンにソフトウェア エージェントをインストールして、転送をオーケストレートします。

権限を構成する

転送を作成する前に、次のエンティティの権限を構成する必要があります。

転送の作成に使用されるユーザー アカウント。これは、Google Cloud コンソールにログインするアカウント、または gcloud CLI の認証時に指定されたアカウントです。ユーザー アカウントは、通常のユーザー アカウントでも、ユーザーが管理するサービス アカウントでもかまいません。
Storage Transfer Service で使用される Google 管理のサービス アカウント(サービス エージェントとも呼ばれる)。通常、このアカウントは、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 コンソールのストレージの [Data Transfer] ページに移動します。

    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 バケットの名前の 1 つです。必要に応じて、フォルダパスの後にスラッシュが続きます。例: 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}")