分割物件下載

下載大型檔案的其中一種策略稱為「切片物件下載」。 在這種下載作業中,系統會平行發出範圍 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,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

如要下載切片物件,請將 AllowDivideAndConquer 設為 true。 例如:

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 實作自己的物件切片下載策略。

為防止來源物件在下載期間變更而導致資料損毀,您應在每個物件切片下載要求中,提供來源物件的產生版本號碼