スライス化されたオブジェクトのダウンロード

サイズの大きいファイルをダウンロードする方法の一つとしてスライス化されたオブジェクトのダウンロードがあります。このようなダウンロードでは、範囲内の GET リクエストが並列に作成され、事前に割り当てられた一時的な宛先ファイルにデータが保存されます。すべてのスライスがダウンロードされると、一時ファイルの名前が変更され、宛先のファイルが生成されます。

ネットワークとディスクの速度が制限要因になっていない場合、スライス化されたオブジェクトのダウンロードが大幅に高速化されることがあります。ただし、スライス化されたオブジェクトのダウンロードは、ディスク上のさまざまな場所で複数の書き込みが発生する要因となります。このため、このダウンロード戦略では、特にダウンロードを多数のスライスに分割する場合に、シーク時間が長いディスクのパフォーマンスが低下する可能性があります。Google Cloud CLI などのツールでは、パフォーマンスに影響する可能性を最小限に抑えるために、作成するスライス数のデフォルト値が小さく設定されています。

スライス化されたオブジェクトのダウンロードでは、スライスのデータの整合性を検証するため、高速で計算可能なチェックサム(CRC32C)を常に使用する必要があります。スライス化されたオブジェクトのダウンロードを実行するため、gcloud CLI などのツールでは、ダウンロードを実行するマシンにコンパイル済みの crcmod が必要です。コンパイル済みの crcmod を使用できない場合、gcloud CLI は代わりにスライス化されていないオブジェクトのダウンロードを実行します。

ツールと API でスライス化されたオブジェクトのダウンロードが使用される仕組み

Cloud Storage の操作方法によっては、スライス化されたオブジェクトのダウンロードが自動的に管理される場合があります。このセクションでは、さまざまなツールでのスライス化されたオブジェクトのダウンロード動作と、その動作を変更する方法について説明します。

コンソール

Google Cloud コンソールでは、スライス化されたオブジェクトのダウンロードは実行されません。

コマンドライン

デフォルトでは、gcloud storage cp はスライス化されたオブジェクトのダウンロードを有効にします。gcloud CLI でスライス化されたオブジェクトをダウンロードする方法とタイミングは、次のプロパティを変更することで制御できます。

  • storage/sliced_object_download_threshold: スライス化されたオブジェクトのダウンロードを行うファイルの最小合計サイズ。スライス化されたオブジェクトのダウンロードをすべて無効にするには、この値を 0 に設定します。

  • storage/sliced_object_download_max_components: ダウンロードで使用するスライスの最大数。上限を設けない場合、0 に設定します。この場合、スライスの数は storage/sliced_object_download_component_size によってのみ決定されます。

  • storage/sliced_object_download_component_size: 各ダウンロード スライスのターゲット サイズ。ファイルの合計サイズが大きく、このサイズのスライスをダウンロードするために storage/sliced_object_download_max_components で設定可能な数を超えるスライスが必要な場合、このプロパティは無視されます。

これらのプロパティを変更するには、名前付き構成を作成し、プロジェクト全体のフラグの --configuration を使用してコマンドごとに構成を適用するか、gcloud config set コマンドを使用してすべての gcloud CLI コマンドに構成を適用します。

gcloud CLI を使用してスライス化されたオブジェクトのダウンロードを実行する場合、追加のローカル ディスク容量は必要ありません。完了する前にダウンロードが失敗した場合は、コマンドを再度実行して失敗したスライスを再開します。失敗する前に正常にダウンロードされたスライスは、ダウンロードの試行の間にソース オブジェクトが変更された場合を除き、再試行時には再ダウンロードされません。

一時的にダウンロードされたオブジェクトは、名前に _.gstmp という接尾辞が付加されて宛先ディレクトリに表示されます。

クライアント ライブラリ

Java

詳細については、Cloud Storage Java API のリファレンス ドキュメントをご覧ください。

Cloud Storage に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。

スライス化されたオブジェクトのダウンロードを行うには、AllowDivideAndConquertrue に設定します。例:

import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.transfermanager.DownloadResult;
import com.google.cloud.storage.transfermanager.ParallelDownloadConfig;
import com.google.cloud.storage.transfermanager.TransferManager;
import com.google.cloud.storage.transfermanager.TransferManagerConfig;
import java.nio.file.Path;
import java.util.List;

class AllowDivideAndConquerDownload {

  public static void divideAndConquerDownloadAllowed(
      List<BlobInfo> blobs, String bucketName, Path destinationDirectory) {
    TransferManager transferManager =
        TransferManagerConfig.newBuilder()
            .setAllowDivideAndConquerDownload(true)
            .build()
            .getService();
    ParallelDownloadConfig parallelDownloadConfig =
        ParallelDownloadConfig.newBuilder()
            .setBucketName(bucketName)
            .setDownloadDirectory(destinationDirectory)
            .build();
    List<DownloadResult> results =
        transferManager.downloadBlobs(blobs, parallelDownloadConfig).getDownloadResults();

    for (DownloadResult result : results) {
      System.out.println(
          "Download of "
              + result.getInput().getName()
              + " completed with status "
              + result.getStatus());
    }
  }
}

Node.js

詳細については、Cloud Storage Node.js API のリファレンス ドキュメントをご覧ください。

Cloud Storage に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。

スライス化されたオブジェクトのダウンロードを行うには、downloadFileInChunks メソッドを使用します。次に例を示します。

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The ID of the GCS file to download
// const fileName = 'your-file-name';

// The path to which the file should be downloaded
// const destFileName = '/local/path/to/file.txt';

// The size of each chunk to be downloaded
// const chunkSize = 1024;

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

// Creates a client
const storage = new Storage();

// Creates a transfer manager client
const transferManager = new TransferManager(storage.bucket(bucketName));

async function downloadFileInChunksWithTransferManager() {
  // Downloads the files
  await transferManager.downloadFileInChunks(fileName, {
    destination: destFileName,
    chunkSizeBytes: chunkSize,
  });

  console.log(
    `gs://${bucketName}/${fileName} downloaded to ${destFileName}.`
  );
}

downloadFileInChunksWithTransferManager().catch(console.error);

Python

詳細については、Cloud Storage Python API のリファレンス ドキュメントをご覧ください。

Cloud Storage に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。

スライス化されたオブジェクトのダウンロードを行うには、download_chunks_concurrently メソッドを使用します。次に例を示します。

def download_chunks_concurrently(
    bucket_name, blob_name, filename, chunk_size=32 * 1024 * 1024, workers=8
):
    """Download a single file in chunks, concurrently in a process pool."""

    # The ID of your GCS bucket
    # bucket_name = "your-bucket-name"

    # The file to be downloaded
    # blob_name = "target-file"

    # The destination filename or path
    # filename = ""

    # The size of each chunk. The performance impact of this value depends on
    # the use case. The remote service has a minimum of 5 MiB and a maximum of
    # 5 GiB.
    # chunk_size = 32 * 1024 * 1024 (32 MiB)

    # The maximum number of processes to use for the operation. The performance
    # impact of this value depends on the use case, but smaller files usually
    # benefit from a higher number of processes. Each additional process occupies
    # some CPU and memory resources until finished. Threads can be used instead
    # of processes by passing `worker_type=transfer_manager.THREAD`.
    # workers=8

    from google.cloud.storage import Client, transfer_manager

    storage_client = Client()
    bucket = storage_client.bucket(bucket_name)
    blob = bucket.blob(blob_name)

    transfer_manager.download_chunks_concurrently(
        blob, filename, chunk_size=chunk_size, max_workers=workers
    )

    print("Downloaded {} to {}.".format(blob_name, filename))

REST API

JSON APIXML API は、どちらも範囲指定された GET リクエストをサポートしています。どちらの API を使用しても、独自のスライス化されたオブジェクト ダウンロード戦略を実装できます。

ダウンロード中にソース オブジェクトの変更によるデータ破損から保護するには、オブジェクトのスライスで、ダウンロード リクエストごとにソース オブジェクトの世代番号を付与する必要があります。