Descargas de objetos divididos

Una estrategia para descargar archivos grandes se llama descargas de objetos divididos. En esta descarga, se realizan solicitudes GET en rango en paralelo y se almacenan datos dentro de un archivo de destino temporal asignado con anterioridad. Una vez que se hayan descargado todas las porciones, se cambiará el nombre del archivo temporal al de destino.

Las descargas de objetos divididos pueden ser mucho más rápidas si la velocidad de la red y el disco no son factores limitantes. Sin embargo, las descargas de objetos divididos provocan que se realicen varias escrituras en varias ubicaciones del disco, por lo que esta estrategia de descarga puede degradar el rendimiento de los discos con tiempos de búsqueda lentos, en especial cuando se divide una descarga en una gran cantidad de porciones. Las herramientas como Google Cloud CLI tienen valores predeterminados bajos para la cantidad de porciones que crean a fin de minimizar la posibilidad de impactos en el rendimiento.

Las descargas de objetos divididos siempre deben usar una suma de verificación rápida compuesta (CRC32C) para verificar la integridad de los datos de las porciones. Para realizar descargas de objetos divididos, las herramientas como gcloud CLI requieren que una versión compilada de crcmod en la máquina que realice la descarga. Si crcmod compilado no está disponible, la CLI de gcloud realiza descargas de objetos sin dividir.

Cómo las herramientas y las APIs usan las descargas de objetos divididos

Según cómo interactúes con Cloud Storage, las descargas de objetos divididos pueden administrarse de forma automática en tu nombre. En esta sección, se describe el comportamiento de descarga de objetos divididos para diferentes herramientas y se proporciona información sobre cómo puedes modificar el comportamiento.

Console

La consola de Google Cloud no realiza descargas de objetos divididos.

Línea de comandos

De forma predeterminada, gcloud storage cp habilita las descargas de objetos divididos. Puedes controlar cómo y cuándo gcloud CLI realiza descargas de objetos divididos si modificas las siguientes propiedades:

  • storage/sliced_object_download_threshold: El tamaño total mínimo del archivo para realizar una descarga de objetos divididos. Puedes inhabilitar todas las descargas de objetos divididos estableciendo este valor en 0.

  • storage/sliced_object_download_max_components: La cantidad máxima de porciones que se usarán en la descarga. Establece este valor en 0 para que no haya límite, en cuyo caso la cantidad de porciones se determina solo mediante storage/sliced_object_download_component_size.

  • storage/sliced_object_download_component_size: El tamaño de destino de cada porción de descarga. Esta propiedad se ignora si el tamaño total del archivo es tan grande que la descarga de porciones de este tamaño requeriría más divisiones de las permitidas, como se establece en storage/sliced_object_download_max_components.

Puedes modificar estas propiedades si creas una configuración con nombre y aplicas la configuración por comando mediante la marca --configuration de todo el proyecto o para todos los comandos de gcloud CLI con el comando gcloud config set.

No se requiere espacio en el disco local adicional cuando se usa gcloud CLI para realizar descargas de objetos divididos. Si la descarga falla antes de completarse, ejecuta el comando de nuevo para reanudar las porciones que fallaron. Las porciones que se descargaron de forma correcta antes de la falla no se vuelven a descargar cuando vuelves a intentarlo, excepto en el caso en el que el objeto de origen haya cambiado entre intentos de descarga.

Los objetos temporales descargados aparecen en el directorio de destino con el sufijo _.gstmp en su nombre.

Bibliotecas cliente

Java

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage Java.

Para autenticarte en Cloud Storage, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

Puedes realizar descargas de objetos divididos; para ello, establece AllowDivideAndConquer en true. Por ejemplo:

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

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage Node.js.

Para autenticarte en Cloud Storage, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

Puedes realizar descargas de objetos divididos con el método downloadFileInChunks. Por ejemplo:

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

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage Python.

Para autenticarte en Cloud Storage, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

Puedes realizar descargas de objetos divididos con el método download_chunks_concurrently. Por ejemplo:

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

API de REST

La API de JSON y la API de XML admiten solicitudes GET con rangos, lo que significa que puedes usar cualquiera de las APIs para implementar tu propia estrategia de descarga de objetos divididos.

Con el fin de estar protegido contra la corrupción de datos debido a que el objeto de origen cambia durante la descarga, debes proporcionar el número de generación del objeto de origen en cada solicitud de descarga de una porción del objeto.