Downloads de objetos divididos

Uma estratégia para fazer o download de arquivos grandes é chamada de downloads de objetos divididos. Nesse download, as solicitações GET por intervalo são feitas em paralelo, armazenando dados em um arquivo de destino temporário e pré-alocado. Depois que o download de todas as frações é concluído, o arquivo temporário é renomeado como o arquivo de destino.

Os downloads de objetos divididos poderão ser significativamente mais rápidos se as velocidades da rede e do disco não tiverem fatores limitantes. No entanto, os downloads de objetos divididos fazem com que várias gravações ocorram em vários locais no disco. Por isso, essa estratégia de download pode prejudicar o desempenho de discos com tempos de busca lentos, especialmente ao dividir um download em um grande número de frações. Ferramentas como a CLI do Google Cloud têm valores padrão baixos para o número de frações criadas a fim de minimizar a possibilidade de impactos no desempenho.

Os downloads de objetos divididos precisam sempre usar uma soma de verificação (CRC32C) rápida combinável para verificar a integridade de dados das frações. Para executar downloads de objetos fracionados, ferramentas como a gcloud CLI exigem uma versão compilada do crcmod na máquina que executa o download. Se o crcmod compilado não estiver disponível, a CLI gcloud vai realizar downloads de objetos sem divisão.

Como ferramentas e APIs usam downloads de objetos divididos

Dependendo de como você interage com o Cloud Storage, os downloads de objetos divididos podem ser gerenciados automaticamente para você. Esta seção descreve o comportamento de download de objetos divididos em diferentes ferramentas e fornece informações sobre como modificar esse comportamento.

Console

O console do Google Cloud não faz o download de objetos divididos.

Linha de comando

Por padrão, o gcloud storage cp permite downloads de objetos divididos. É possível controlar como e quando a gcloud CLI executa downloads de objetos fracionados modificando as propriedades a seguir:

  • storage/sliced_object_download_threshold: o tamanho mínimo total do arquivo para fazer um download de objeto dividido. É possível desativar todos os downloads de objetos divididos definindo esse valor como 0.

  • storage/sliced_object_download_max_components: o número máximo de frações a serem usadas no download. Defina 0 para sem limite. Nesse caso, o número de frações será determinado exclusivamente pelo storage/sliced_object_download_component_size.

  • storage/sliced_object_download_component_size: o tamanho do destino de cada fração do download. Essa propriedade será ignorada se o tamanho total do arquivo for tão grande que fazer o download de frações desse tamanho exigiria mais frações do que o permitido, conforme definido em storage/sliced_object_download_max_components.

É possível modificar essas propriedades criando uma configuração nomeada e aplicando a configuração por comando usando a flag --configuration em todo o projeto ou para todos os comandos da gcloud CLI usando o comando gcloud config set.

Nenhum espaço extra em disco local é necessário ao usar a CLI gcloud para executar downloads de objetos fatiados. Se o download falhar antes da conclusão, execute novamente o comando para retomar as frações que falharam. Os downloads das frações concluídos antes da falha não são refeitos ao tentar novamente, exceto quando o objeto de origem é alterado entre as tentativas de download.

Os downloads de objetos temporários aparecem no diretório de destino com o sufixo _.gstmp no nome.

Bibliotecas de cliente

Java

Para mais informações, consulte a documentação de referência da API Cloud Storage Java.

Para autenticar no Cloud Storage, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

É possível fazer downloads de objetos divididos definindo AllowDivideAndConquer como true. Exemplo:

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

Para mais informações, consulte a documentação de referência da API Cloud Storage Node.js.

Para autenticar no Cloud Storage, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

É possível fazer downloads de objetos fatiados usando o método downloadFileInChunks. Exemplo:

/**
 * 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

Para mais informações, consulte a documentação de referência da API Cloud Storage Python.

Para autenticar no Cloud Storage, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

É possível fazer downloads de objetos fatiados usando o método download_chunks_concurrently. Exemplo:

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

APIs REST

A API JSON e a API XML são compatíveis com solicitações GET por intervalo. Isso significa que é possível usar qualquer uma das APIs para implementar sua própria estratégia de downloads de objetos divididos.

Para prevenir a corrupção de dados devido à alteração do objeto de origem durante o download, informe o número de geração do objeto de origem em cada solicitação de download de uma fração do objeto.