Descargas de objetos segmentados

Una estrategia para descargar archivos grandes se denomina descarga de objetos segmentados. En este tipo de descarga, las solicitudes GET se realizan en paralelo y los datos se almacenan en un archivo de destino temporal preasignado. Una vez que se hayan descargado todos los segmentos, se cambiará el nombre del archivo temporal por el del archivo de destino.

Las descargas de objetos segmentados pueden ser significativamente más rápidas si la velocidad de la red y del disco no son factores limitantes. Sin embargo, las descargas de objetos segmentados provocan que se realicen varias escrituras en diferentes ubicaciones del disco, por lo que esta estrategia de descarga puede reducir el rendimiento de los discos con tiempos de búsqueda lentos, especialmente cuando se divide una descarga en un gran número de segmentos. Herramientas como la CLI de Google Cloud tienen valores predeterminados bajos para el número de segmentos que crean con el fin de minimizar la posibilidad de que afecten al rendimiento.

Las descargas de objetos segmentados siempre deben usar una suma de comprobación rápida y componible (CRC32C) para verificar la integridad de los datos de los segmentos. Para descargar objetos segmentados, herramientas como la CLI de gcloud requieren una versión compilada de crcmod en la máquina que realiza la descarga. Si crcmod compilado no está disponible, la CLI de gcloud realiza descargas de objetos sin segmentar.

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

En función de cómo interactúes con Cloud Storage, es posible que las descargas de objetos segmentados se gestionen automáticamente en tu nombre. En esta sección se describe el comportamiento de descarga de objetos segmentados en diferentes herramientas y se explica cómo puede modificarlo.

Consola

La consola Google Cloud no descarga objetos segmentados.

Línea de comandos

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

  • storage/sliced_object_download_threshold: tamaño total mínimo del archivo para realizar una descarga de objetos segmentada. Para inhabilitar todas las descargas de objetos segmentados, asigna el valor 0 a este atributo.

  • storage/sliced_object_download_max_components: número máximo de segmentos que se pueden usar en la descarga. Asigne el valor 0 para que no haya límite. En ese caso, el número de porciones se determinará únicamente por storage/sliced_object_download_component_size.

  • storage/sliced_object_download_component_size: tamaño objetivo de cada segmento de descarga. Esta propiedad se ignora si el tamaño total del archivo es tan grande que, para descargar segmentos de este tamaño, se necesitarían más segmentos de los permitidos, tal como se define en storage/sliced_object_download_max_components.

Puedes modificar estas propiedades creando una configuración con nombre y aplicándola a cada comando mediante la marca --configuration de todo el proyecto o a todos los comandos de la CLI de gcloud mediante el comando gcloud config set.

No se necesita espacio adicional en el disco local cuando se usa la CLI de gcloud para descargar objetos segmentados. Si la descarga falla antes de completarse, vuelve a ejecutar el comando para reanudar los segmentos que han fallado. Las porciones que se hayan descargado correctamente antes del error no se volverán a descargar cuando lo intentes de nuevo, excepto si el objeto de origen ha cambiado entre los intentos de descarga.

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

Bibliotecas de cliente

Java

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

Para autenticarte en Cloud Storage, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación para bibliotecas de cliente.

Para descargar objetos segmentados, define AllowDivideAndConquer como 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

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

Para autenticarte en Cloud Storage, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación para bibliotecas de cliente.

Puedes descargar objetos segmentados 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

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

Para autenticarte en Cloud Storage, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación para bibliotecas de cliente.

Puedes descargar objetos segmentados 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))

APIs REST

Tanto la API JSON como la API XML admiten solicitudes GET por intervalos, lo que significa que puedes usar cualquiera de las dos APIs para implementar tu propia estrategia de descarga de objetos segmentados.

Para protegerse frente a la corrupción de datos debido a que el objeto de origen cambie durante la descarga, debe proporcionar el número de generación del objeto de origen en cada solicitud de descarga de una porción del objeto.