Uso de las cargas multiparte con buckets de directorio - Amazon Simple Storage Service

Uso de las cargas multiparte con buckets de directorio

Puede usar el proceso de carga multiparte para cargar un solo objeto como un conjunto de partes. Cada parte es una parte contigua de los datos del objeto. Puede cargar estas partes del objeto de forma independiente y en cualquier orden. Si la transmisión de cualquier parte falla, puede retransmitir esta parte sin que las demás partes se vean afectadas. Después de cargar todas las partes del objeto, Amazon S3 las combina y crea el objeto. Por lo general, cuando el tamaño del objeto alcanza los 100 MB, deberá usar las cargas multipartes en lugar de cargar el objeto en una única operación.

El uso de la carga multiparte proporciona las siguientes ventajas:

  • Mayor rendimiento: puede cargar las partes al mismo tiempo para aumentar el rendimiento.

  • Recuperación rápida ante cualquier problema de red: una parte de tamaño más pequeño minimiza el impacto de tener que reiniciar una carga fallida debido a un error de red.

  • Detención y reanudación de cargas de objetos: puede cargar las partes del objeto con el paso del tiempo. Después de iniciar una carga multiparte, no hay fecha de caducidad. Debe completar o anular la carga multiparte de forma explícita.

  • Inicio de una carga antes de conocer el tamaño final del objeto: puede cargar un objeto a medida que lo crea.

Le recomendamos que use las cargas multiparte de las siguientes maneras:

  • Si carga objetos grandes en una red de banda ancha estable, use las cargas multiparte para aumentar al máximo el uso del ancho de banda disponible cargando las partes de objetos en paralelo para obtener un rendimiento en varios subprocesos.

  • Si realiza la carga en una red irregular, use las cargas multiparte para aumentar la resiliencia ante errores de red para evitar reiniciar la carga. Al usar las cargas multiparte, debe volver a intentar cargar solo las partes que se han interrumpido durante la carga. No necesita reiniciar la carga de su objeto desde el principio.

Si utiliza cargas multiparte para cargar objetos a la clase de almacenamiento Amazon S3 Express One Zone en buckets de directorio, el proceso de carga multiparte es similar al proceso de utilizar la carga multiparte para cargar objetos en buckets de uso general. Sin embargo, hay algunas diferencias notables.

Para obtener más información sobre el uso de las cargas multiparte para cargar objetos en S3 Express One Zone, consulte los siguientes temas.

El proceso de carga multiparte

Una carga multiparte es un proceso de tres pasos:

  • Usted inicia la carga.

  • Usted carga las partes del objeto.

  • Después de cargar todas las partes, completa la carga multiparte.

Al recibir la solicitud de carga multiparte completa, Amazon S3 construye el objeto a partir de las partes cargadas para que pueda obtener acceso al objeto como lo haría con cualquier otro objeto de su bucket.

Inicio de la carga multiparte

Al enviar una solicitud para iniciar una carga multiparte, Amazon S3 devuelve una respuesta con un ID de carga, que es un identificador único para su carga multiparte. Debe incluir este ID de carga siempre que cargue las partes, enumera las partes, completa una carga o la anula.

Carga de partes

Al cargar una parte, además del ID de carga, debe especificar un número de parte. Al utilizar una carga multiparte con S3 Express One Zone, los números de las partes multiparte deben ser consecutivos. Si intenta completar una solicitud de carga multiparte con números de partes no consecutivos, se genera un error HTTP 400 Bad Request (número de parte no válido).

Un número de parte identifica una parte de forma exclusiva y su posición en el objeto que se está cargando. Si carga una parte nueva con el mismo número que una parte ya cargada, se anulará la parte existente.

Siempre que cargue una parte, Amazon S3 devolverá un encabezado de etiqueta de entidad (ETag) en la respuesta. Para cada carga de parte, debe anotar el número de parte y el valor de ETag. Los valores de ETag para todas las cargas de partes de objeto seguirán siendo los mismos, pero a cada parte se le asignará un número de pieza diferente. Debe incluir estos valores en la solicitud posterior para completar la carga multiparte.

Amazon S3 cifra automáticamente todos los objetos nuevos que se cargan a un bucket de S3. Al realizar una carga multiparte, si no especifica la información de cifrado en su solicitud, la configuración de cifrado de las partes cargadas se establece con la configuración de cifrado predeterminada del bucket de destino. La configuración de cifrado predeterminada de un bucket de Amazon S3 siempre está habilitada y, como mínimo, se establece para el cifrado del servidor con claves administradas de Amazon S3 (SSE-S3). Para los buckets de directorio, se admiten SSE-S3 y el cifrado del servidor con claves de AWS KMS (SSE-KMS). Para obtener más información, consulte Protección y cifrado de datos en S3 Express One Zone.

Finalización de la carga multiparte

Al completar una carga multiparte, Amazon S3 crea un objeto al concatenar las partes en orden ascendente según el número de parte. Después de una solicitud de completar realizada correctamente, las partes ya no existirán.

La solicitud carga multiparte completa debe incluir el ID de carga y una lista de ambos números de parte y sus valores ETag correspondientes. La respuesta de Amazon S3 incluye una ETag que identifica de forma exclusiva los datos de objetos combinados. Esta ETag no es un hash de MD5 de los datos del objeto.

Listas de cargas multiparte

Puede enumerar las partes de una carga multiparte específica o todas las cargas multipartes en curso. La operación de lista de partes devuelve la información de las partes que ha cargado para una carga multiparte específica. Para cada solicitud de lista de partes, Amazon S3 devuelve la información de las partes para la carga multiparte específica, hasta un máximo de 1000 partes. Si hay más de 1000 partes en la carga multiparte, debe usar la paginación para recuperar todas las partes.

La lista de partes que se devuelve no incluye las partes que no se hayan cargado por completo. Con la operación lista de cargas multiparte, puede obtener una lista de las cargas multiparte en curso.

Una carga multiparte en curso es una carga iniciada pero que aún no se ha completado ni anulado. Cada solicitud devuelve 1 000 cargas multipartes como máximo. Si hay más de 1 000 cargas multiparte en curso, debe enviar otras solicitudes para recuperar las cargas multiparte restantes. Solo utilice la lista devuelta para fines de verificación. No utilice el resultado de esta lista al enviar una solicitud para completar la carga multiparte. En cambio, mantenga su propia lista de números de parte que especificó al cargarlas y los valores correspondientes de ETag que devuelve Amazon S3.

Para obtener más información sobre las listas de carga multiparte, consulte ListParts en la Referencia de la API de Amazon Simple Storage Service.

Sumas de comprobación con operaciones de carga multiparte

Al cargar un objeto, es posible especificar un algoritmo de suma de comprobación para comprobar la integridad del objeto. Los buckets de directorio no admiten MD5. Puede especificar uno de los siguientes algoritmos de comprobación de integridad de datos Secure Hash Algoritms (SHA) o Cyclic Redundancy Check (CRC):

  • CRC32

  • CRC 32C

  • SHA-1

  • SHA-256

Puede utilizar la API de REST de Amazon S3 o el SDK de AWS para obtener el valor de la suma de comprobación de partes individuales mediante GetObject o HeadObject. Si quiere recuperar los valores de la suma de comprobación de partes individuales de las cargas multiparte que aún están en proceso, puede utilizar ListParts.

importante

Al utilizar los algoritmos de suma de comprobación anteriores, los números de partes multiparte deben ser consecutivos. Si intenta completar una solicitud de carga multiparte con números de partes no consecutivos, Amazon S3 genera un error HTTP 400 Bad Request (número de parte no válido).

Para obtener más información sobre cómo funcionan las sumas de comprobación con objetos multiparte, consulte Comprobación de la integridad de objetos.

Operaciones de carga multiparte simultáneas

En un entorno de desarrollo distribuido, es posible que la aplicación inicie varias actualizaciones en el mismo objeto simultáneamente. Por ejemplo, la aplicación puede iniciar varias cargas multiparte con la misma clave de objeto. Para cada una de estas cargas, la aplicación puede cargar las partes y enviar una solicitud de carga completa a Amazon S3 para crear el objeto. Para S3 Express One Zone, la hora de creación del objeto es la fecha de finalización de la carga multiparte.

importante

No se admite el control de versiones para los objetos almacenados en los buckets de directorio.

Cargas multiparte y precios

Después de iniciar una carga multiparte, Amazon S3 retiene todas las partes hasta que complete o anule la carga. Durante la vida útil, se le cobrará por todo el almacenamiento, el ancho de banda y las solicitudes para esta carga multiparte y sus partes asociadas. Si anula la carga multiparte, no se le cobrará por estos elementos, ya que Amazon S3 elimina los artefactos cargados y cualquier parte que haya cargado. No se cobran gastos de eliminación anticipada por eliminar cargas multiparte incompletas, independientemente de la clase de almacenamiento especificada. Para obtener más información acerca de los precios, consulte Precios de Amazon S3.

importante

Si la solicitud de carga multiparte completa no se envía correctamente, las partes del objeto no se ensamblan y no se crea un objeto. Se facturará todo el almacenamiento asociado con las partes cargadas. Es importante que complete la carga multiparte para que se cree el objeto o anule la carga multiparte a fin de eliminar las partes cargadas.

Antes de eliminar un bucket de directorio, debe completar o anular todas las cargas multiparte en curso. Los buckets de directorio no admiten las configuraciones de S3 Lifecycle. Si es necesario, puede elaborar una lista de cargas multiparte activas, anular las cargas y, por último, eliminar el bucket.

Operaciones de la API y permisos de carga multiparte

Para permitir el acceso a las operaciones de la API de administración de objetos en un bucket de directorio, debe conceder el permiso s3express:CreateSession en una política de bucket o una política de AWS Identity and Access Management (IAM) basada en identidades.

Debe tener los permisos necesarios para utilizar las operaciones de carga multiparte. Puede usar políticas de bucket o políticas de IAM basadas en identidades para conceder permisos a las entidades principales de IAM para realizar estas operaciones. En la siguiente tabla se muestran los permisos requeridos para varias operaciones de carga multiparte.

Puede identificar al iniciador de una carga multiparte mediante el elemento Initiator. Si el iniciador es una Cuenta de AWS, este elemento proporcionará la misma información que el elemento Owner. Si el iniciador es un usuario de IAM, este elemento proporciona el ARN de usuario y el nombre para mostrar.

Acción Permisos necesarios

Crear una carga multiparte

Para poder crear la carga multiparte, debe tener permiso para realizar la acción s3express:CreateSession en el bucket de directorio.

Iniciar una carga multiparte

Para iniciar la carga multiparte, debe tener permiso para realizar la acción s3express:CreateSession en el bucket de directorio.

Cargar una parte

Para cargar una parte, debe tener permiso para realizar la acción s3express:CreateSession en el bucket de directorio.

El propietario del bucket debe permitir al iniciador realizar la acción s3express:CreateSession en un bucket de directorio para que el iniciador pueda cargar la parte.

Cargar una parte (copia)

Para cargar una parte, debe tener permiso para realizar la acción s3express:CreateSession en el bucket de directorio.

Para que el iniciador cargue una parte del objeto, el propietario del bucket debe permitir al iniciador realizar la acción s3express:CreateSession en un objeto.

Completar una carga multiparte

Para completar una carga multiparte, debe tener permiso para realizar la acción s3express:CreateSession en el bucket de directorio.

El propietario del bucket debe permitir al iniciador realizar la acción s3express:CreateSession en un objeto para que el iniciador pueda completar la carga multiparte.

Anular una carga multiparte

Para anular una carga multiparte, debe tener permiso para realizar la acción s3express:CreateSession.

Para que pueda anular la carga multiparte, se debe conceder al iniciador un permiso de acceso explícito para realizar la acción s3express:CreateSession.

Enumerar las partes

Para enumerar las partes de una carga multiparte, debe tener permiso para realizar la acción s3express:CreateSession en el bucket de directorio.

Obtenga una lista de las cargas multiparte en curso

Para enumerar las cargas multiparte en curso de un bucket, debe tener permiso para realizar la acción s3:ListBucketMultipartUploads en dicho bucket.

Compatibilidad de la operación de la API con las cargas multiparte

En las siguientes secciones de la referencia de la API de Amazon Simple Storage Service se describen las operaciones de la API de REST de Amazon S3 para las cargas multiparte.

Ejemplos

Para usar una carga multiparte para cargar un objeto en S3 Express One Zone en un bucket de directorio, consulte los siguientes ejemplos.

Creación de una carga multiparte

nota

Para los buckets de directorio, cuando realiza una operación CreateMultipartUpload y una operación UploadPartCopy, el cifrado predeterminado del bucket debe usar la configuración de cifrado deseada y los encabezados de solicitud que proporcione en la solicitud de CreateMultipartUpload deben coincidir con la configuración de cifrado predeterminada del bucket de destino.

En el siguiente ejemplo, se muestra cómo detener una carga multiparte.

SDK for Java 2.x
/** * This method creates a multipart upload request that generates a unique upload ID that is used to track * all the upload parts * * @param s3 * @param bucketName - for example, 'doc-example-bucket--use1-az4--x-s3' * @param key * @return */ private static String createMultipartUpload(S3Client s3, String bucketName, String key) { CreateMultipartUploadRequest createMultipartUploadRequest = CreateMultipartUploadRequest.builder() .bucket(bucketName) .key(key) .build(); String uploadId = null; try { CreateMultipartUploadResponse response = s3.createMultipartUpload(createMultipartUploadRequest); uploadId = response.uploadId(); } catch (S3Exception e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return uploadId;
SDK for Python
def create_multipart_upload(s3_client, bucket_name, key_name): ''' Create a multipart upload to a directory bucket :param s3_client: boto3 S3 client :param bucket_name: The destination bucket for the multipart upload :param key_name: The key name for the object to be uploaded :return: The UploadId for the multipart upload if created successfully, else None ''' try: mpu = s3_client.create_multipart_upload(Bucket = bucket_name, Key = key_name) return mpu['UploadId'] except ClientError as e: logging.error(e) return None

En este ejemplo se muestra cómo crear una carga multiparte en un bucket de directorio con la AWS CLI. Este comando inicia una carga multiparte en el bucket de directorio bucket-base-name--azid--x-s3 para el objeto KEY_NAME. Para usar el comando, sustituya los marcadores de posición de entrada del usuario con su propia información.

aws s3api create-multipart-upload --bucket bucket-base-name--azid--x-s3 --key KEY_NAME

Para obtener más información, consulte create-multipart-upload en la AWS Command Line Interface.

Carga de las partes de una carga multiparte

En los siguientes ejemplos de código se muestra cómo cargar partes de una carga multiparte.

SDK for Java 2.x

En los siguientes ejemplos se muestra cómo dividir un objeto en partes y, a continuación, cargar esas partes en un bucket de directorio con el SDK para Java 2.x.

/** * This method creates part requests and uploads individual parts to S3 and then returns all the completed parts * * @param s3 * @param bucketName * @param key * @param uploadId * @throws IOException */ private static ListCompletedPartmultipartUpload(S3Client s3, String bucketName, String key, String uploadId, String filePath) throws IOException { int partNumber = 1; ListCompletedPart completedParts = new ArrayList<>(); ByteBuffer bb = ByteBuffer.allocate(1024 * 1024 * 5); // 5 MB byte buffer // read the local file, breakdown into chunks and process try (RandomAccessFile file = new RandomAccessFile(filePath, "r")) { long fileSize = file.length(); int position = 0; while (position < fileSize) { file.seek(position); int read = file.getChannel().read(bb); bb.flip(); // Swap position and limit before reading from the buffer. UploadPartRequest uploadPartRequest = UploadPartRequest.builder() .bucket(bucketName) .key(key) .uploadId(uploadId) .partNumber(partNumber) .build(); UploadPartResponse partResponse = s3.uploadPart( uploadPartRequest, RequestBody.fromByteBuffer(bb)); CompletedPart part = CompletedPart.builder() .partNumber(partNumber) .eTag(partResponse.eTag()) .build(); completedParts.add(part); bb.clear(); position += read; partNumber++; } } catch (IOException e) { throw e; } return completedParts; }
SDK for Python

En los siguientes ejemplos se muestra cómo dividir un objeto en partes y, a continuación, cargar esas partes en un bucket de directorio con el SDK para Python.

def multipart_upload(s3_client, bucket_name, key_name, mpu_id, part_size): ''' Break up a file into multiple parts and upload those parts to a directory bucket :param s3_client: boto3 S3 client :param bucket_name: Destination bucket for the multipart upload :param key_name: Key name for object to be uploaded and for the local file that's being uploaded :param mpu_id: The UploadId returned from the create_multipart_upload call :param part_size: The size parts that the object will be broken into, in bytes. Minimum 5 MiB, Maximum 5 GiB. There is no minimum size for the last part of your multipart upload. :return: part_list for the multipart upload if all parts are uploaded successfully, else None ''' part_list = [] try: with open(key_name, 'rb') as file: part_counter = 1 while True: file_part = file.read(part_size) if not len(file_part): break upload_part = s3_client.upload_part( Bucket = bucket_name, Key = key_name, UploadId = mpu_id, Body = file_part, PartNumber = part_counter ) part_list.append({'PartNumber': part_counter, 'ETag': upload_part['ETag']}) part_counter += 1 except ClientError as e: logging.error(e) return None return part_list

En los siguientes ejemplos se muestra cómo dividir un objeto en partes y, a continuación, cargar esas partes en un bucket de directorio con la AWS CLI. Para usar el comando, sustituya los marcadores de posición de entrada del usuario con su propia información.

aws s3api upload-part --bucket bucket-base-name--azid--x-s3 --key KEY_NAME --part-number 1 --body LOCAL_FILE_NAME --upload-id "AS_mgt9RaQE9GEaifATue15dAAAAAAAAAAEMAAAAAAAAADQwNzI4MDU0MjUyMBYAAAAAAAAAAA0AAAAAAAAAAAH2AfYAAAAAAAAEBSD0WBKMAQAAAABneY9yBVsK89iFkvWdQhRCcXohE8RbYtc9QvBOG8tNpA"

Para obtener más información, consulte upload-part en la AWS Command Line Interface.

Finalización de una carga multiparte

En los siguientes ejemplos se muestra cómo completar una carga multiparte.

SDK for Java 2.x

En los siguientes ejemplos se muestra cómo completar una carga multiparte con el SDK para Java 2.x.

/** * This method completes the multipart upload request by collating all the upload parts * @param s3 * @param bucketName - for example, 'doc-example-bucket--usw2-az1--x-s3' * @param key * @param uploadId * @param uploadParts */ private static void completeMultipartUpload(S3Client s3, String bucketName, String key, String uploadId, ListCompletedPart uploadParts) { CompletedMultipartUpload completedMultipartUpload = CompletedMultipartUpload.builder() .parts(uploadParts) .build(); CompleteMultipartUploadRequest completeMultipartUploadRequest = CompleteMultipartUploadRequest.builder() .bucket(bucketName) .key(key) .uploadId(uploadId) .multipartUpload(completedMultipartUpload) .build(); s3.completeMultipartUpload(completeMultipartUploadRequest); } public static void multipartUploadTest(S3Client s3, String bucketName, String key, String localFilePath) { System.out.println("Starting multipart upload for: " + key); try { String uploadId = createMultipartUpload(s3, bucketName, key); System.out.println(uploadId); ListCompletedPart parts = multipartUpload(s3, bucketName, key, uploadId, localFilePath); completeMultipartUpload(s3, bucketName, key, uploadId, parts); System.out.println("Multipart upload completed for: " + key); } catch (Exception e) { System.err.println(e.getMessage()); System.exit(1); } }
SDK for Python

En los siguientes ejemplos se muestra cómo completar una carga multiparte con el SDK para Python.

def complete_multipart_upload(s3_client, bucket_name, key_name, mpu_id, part_list): ''' Completes a multipart upload to a directory bucket :param s3_client: boto3 S3 client :param bucket_name: The destination bucket for the multipart upload :param key_name: The key name for the object to be uploaded :param mpu_id: The UploadId returned from the create_multipart_upload call :param part_list: The list of uploaded part numbers with their associated ETags :return: True if the multipart upload was completed successfully, else False ''' try: s3_client.complete_multipart_upload( Bucket = bucket_name, Key = key_name, UploadId = mpu_id, MultipartUpload = { 'Parts': part_list } ) except ClientError as e: logging.error(e) return False return True if __name__ == '__main__': MB = 1024 ** 2 region = 'us-west-2' bucket_name = 'BUCKET_NAME' key_name = 'OBJECT_NAME' part_size = 10 * MB s3_client = boto3.client('s3', region_name = region) mpu_id = create_multipart_upload(s3_client, bucket_name, key_name) if mpu_id is not None: part_list = multipart_upload(s3_client, bucket_name, key_name, mpu_id, part_size) if part_list is not None: if complete_multipart_upload(s3_client, bucket_name, key_name, mpu_id, part_list): print (f'{key_name} successfully uploaded through a ultipart upload to {bucket_name}') else: print (f'Could not upload {key_name} hrough a multipart upload to {bucket_name}')

En este ejemplo se muestra cómo completar una carga multiparte para un bucket de directorio con la AWS CLI. Para usar el comando, sustituya los marcadores de posición de entrada del usuario con su propia información.

aws s3api complete-multipart-upload --bucket bucket-base-name--azid--x-s3 --key KEY_NAME --upload-id "AS_mgt9RaQE9GEaifATue15dAAAAAAAAAAEMAAAAAAAAADQwNzI4MDU0MjUyMBYAAAAAAAAAAA0AAAAAAAAAAAH2AfYAAAAAAAAEBSD0WBKMAQAAAABneY9yBVsK89iFkvWdQhRCcXohE8RbYtc9QvBOG8tNpA" --multipart-upload file://parts.json

Este ejemplo utiliza una estructura JSON que describe las partes de la carga multiparte que se deben volver a ensamblar en el archivo completo. En este ejemplo, el prefijo file:// se usa para cargar la estructura JSON desde un archivo de la carpeta local denominada parts.

parts.json:

parts.json { "Parts": [ { "ETag": "6b78c4a64dd641a58dac8d9258b88147", "PartNumber": 1 } ] }

Para obtener más información, consulte create-multipart-upload en la AWS Command Line Interface.

Anulación de la carga multiparte

En el siguiente ejemplo se muestra cómo anular una carga multiparte.

SDK for Java 2.x

En el siguiente ejemplo se muestra cómo anular una carga multiparte con el SDK para Java 2.x.

public static void abortMultiPartUploads( S3Client s3, String bucketName ) { try { ListMultipartUploadsRequest listMultipartUploadsRequest = ListMultipartUploadsRequest.builder() .bucket(bucketName) .build(); ListMultipartUploadsResponse response = s3.listMultipartUploads(listMultipartUploadsRequest); ListMultipartUpload uploads = response.uploads(); AbortMultipartUploadRequest abortMultipartUploadRequest; for (MultipartUpload upload: uploads) { abortMultipartUploadRequest = AbortMultipartUploadRequest.builder() .bucket(bucketName) .key(upload.key()) .uploadId(upload.uploadId()) .build(); s3.abortMultipartUpload(abortMultipartUploadRequest); } } catch (S3Exception e) { System.err.println(e.getMessage()); System.exit(1); } }
SDK for Python

En el siguiente ejemplo se muestra cómo anular una carga multiparte con el SDK para Python.

import logging import boto3 from botocore.exceptions import ClientError def abort_multipart_upload(s3_client, bucket_name, key_name, upload_id): ''' Aborts a partial multipart upload in a directory bucket. :param s3_client: boto3 S3 client :param bucket_name: Bucket where the multipart upload was initiated - for example, 'doc-example-bucket--usw2-az1--x-s3' :param key_name: Name of the object for which the multipart upload needs to be aborted :param upload_id: Multipart upload ID for the multipart upload to be aborted :return: True if the multipart upload was successfully aborted, False if not ''' try: s3_client.abort_multipart_upload( Bucket = bucket_name, Key = key_name, UploadId = upload_id ) except ClientError as e: logging.error(e) return False return True if __name__ == '__main__': region = 'us-west-2' bucket_name = 'BUCKET_NAME' key_name = 'KEY_NAME' upload_id = 'UPLOAD_ID' s3_client = boto3.client('s3', region_name = region) if abort_multipart_upload(s3_client, bucket_name, key_name, upload_id): print (f'Multipart upload for object {key_name} in {bucket_name} bucket has been aborted') else: print (f'Unable to abort multipart upload for object {key_name} in {bucket_name} bucket')

En el siguiente ejemplo se muestra cómo anular una carga multiparte con la AWS CLI. Para usar el comando, sustituya los marcadores de posición de entrada del usuario con su propia información.

aws s3api abort-multipart-upload --bucket bucket-base-name--azid--x-s3 --key KEY_NAME --upload-id "AS_mgt9RaQE9GEaifATue15dAAAAAAAAAAEMAAAAAAAAADQwNzI4MDU0MjUyMBYAAAAAAAAAAA0AAAAAAAAAAAH2AfYAAAAAAAAEAX5hFw-MAQAAAAB0OxUFeA7LTbWWFS8WYwhrxDxTIDN-pdEEq_agIHqsbg"

Para obtener más información, consulte abort-multipart-upload en la AWS Command Line Interface.

Creación de una operación de carga y copia multiparte

nota
  • Para cifrar las copias de las partes de los objetos nuevos en un bucket de directorio con SSE-KMS, debe especificar SSE-KMS como la configuración de cifrado predeterminada del bucket de directorios con una clave de KMS (en concreto, una clave administrada por el cliente). Clave administrada de AWS (aws/s3) no se admite. La configuración de SSE-KMS solo admite 1 clave administrada por el cliente por bucket de directorio durante la vida útil del bucket. Después de especificar una clave administrada por el cliente para SSE-KMS, no puede invalidar la clave administrada por el cliente para la configuración de SSE-KMS del bucket. No puede especificar la configuración de cifrado del servidor para las copias de partes de objetos nuevos con SSE-KMS en los encabezados de solicitud de UploadPartCopy. Además, los encabezados de solicitud que proporcione en la solicitud de CreateMultipartUpload deben coincidir con la configuración de cifrado predeterminada del bucket de destino.

  • Las claves de bucket de S3 no son compatibles, cuando se copian objetos cifrados con SSE-KMS de buckets de uso general a buckets de directorio, de buckets de directorio a buckets de uso general o entre buckets de directorio, mediante UploadPartCopy. En ese caso, Amazon S3 realiza una llamada a AWS KMS cada vez que se realiza una solicitud de copia para un objeto cifrado con KMS.

En los siguientes ejemplos se muestra cómo copiar objetos de un bucket a otro mediante una carga multiparte.

SDK for Java 2.x

En el siguiente ejemplo se muestra cómo utilizar una carga multiparte para copiar un objeto mediante programación desde un bucket a otro con el SDK para Java 2.x.

/** * This method creates a multipart upload request that generates a unique upload ID that is used to track * all the upload parts. * * @param s3 * @param bucketName * @param key * @return */ private static String createMultipartUpload(S3Client s3, String bucketName, String key) { CreateMultipartUploadRequest createMultipartUploadRequest = CreateMultipartUploadRequest.builder() .bucket(bucketName) .key(key) .build(); String uploadId = null; try { CreateMultipartUploadResponse response = s3.createMultipartUpload(createMultipartUploadRequest); uploadId = response.uploadId(); } catch (S3Exception e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return uploadId; } /** * Creates copy parts based on source object size and copies over individual parts * * @param s3 * @param sourceBucket * @param sourceKey * @param destnBucket * @param destnKey * @param uploadId * @return * @throws IOException */ public static ListCompletedPart multipartUploadCopy(S3Client s3, String sourceBucket, String sourceKey, String destnBucket, String destnKey, String uploadId) throws IOException { // Get the object size to track the end of the copy operation. HeadObjectRequest headObjectRequest = HeadObjectRequest .builder() .bucket(sourceBucket) .key(sourceKey) .build(); HeadObjectResponse response = s3.headObject(headObjectRequest); Long objectSize = response.contentLength(); System.out.println("Source Object size: " + objectSize); // Copy the object using 20 MB parts. long partSize = 20 * 1024 * 1024; long bytePosition = 0; int partNum = 1; ListCompletedPart completedParts = new ArrayList<>(); while (bytePosition < objectSize) { // The last part might be smaller than partSize, so check to make sure // that lastByte isn't beyond the end of the object. long lastByte = Math.min(bytePosition + partSize - 1, objectSize - 1); System.out.println("part no: " + partNum + ", bytePosition: " + bytePosition + ", lastByte: " + lastByte); // Copy this part. UploadPartCopyRequest req = UploadPartCopyRequest.builder() .uploadId(uploadId) .sourceBucket(sourceBucket) .sourceKey(sourceKey) .destinationBucket(destnBucket) .destinationKey(destnKey) .copySourceRange("bytes="+bytePosition+"-"+lastByte) .partNumber(partNum) .build(); UploadPartCopyResponse res = s3.uploadPartCopy(req); CompletedPart part = CompletedPart.builder() .partNumber(partNum) .eTag(res.copyPartResult().eTag()) .build(); completedParts.add(part); partNum++; bytePosition += partSize; } return completedParts; } public static void multipartCopyUploadTest(S3Client s3, String srcBucket, String srcKey, String destnBucket, String destnKey) { System.out.println("Starting multipart copy for: " + srcKey); try { String uploadId = createMultipartUpload(s3, destnBucket, destnKey); System.out.println(uploadId); ListCompletedPart parts = multipartUploadCopy(s3, srcBucket, srcKey,destnBucket, destnKey, uploadId); completeMultipartUpload(s3, destnBucket, destnKey, uploadId, parts); System.out.println("Multipart copy completed for: " + srcKey); } catch (Exception e) { System.err.println(e.getMessage()); System.exit(1); } }
SDK for Python

En el siguiente ejemplo se muestra cómo utilizar una carga multiparte para copiar un objeto mediante programación desde un bucket a otro con el SDK para Python.

import logging import boto3 from botocore.exceptions import ClientError def head_object(s3_client, bucket_name, key_name): ''' Returns metadata for an object in a directory bucket :param s3_client: boto3 S3 client :param bucket_name: Bucket that contains the object to query for metadata :param key_name: Key name to query for metadata :return: Metadata for the specified object if successful, else None ''' try: response = s3_client.head_object( Bucket = bucket_name, Key = key_name ) return response except ClientError as e: logging.error(e) return None def create_multipart_upload(s3_client, bucket_name, key_name): ''' Create a multipart upload to a directory bucket :param s3_client: boto3 S3 client :param bucket_name: Destination bucket for the multipart upload :param key_name: Key name of the object to be uploaded :return: UploadId for the multipart upload if created successfully, else None ''' try: mpu = s3_client.create_multipart_upload(Bucket = bucket_name, Key = key_name) return mpu['UploadId'] except ClientError as e: logging.error(e) return None def multipart_copy_upload(s3_client, source_bucket_name, key_name, target_bucket_name, mpu_id, part_size): ''' Copy an object in a directory bucket to another bucket in multiple parts of a specified size :param s3_client: boto3 S3 client :param source_bucket_name: Bucket where the source object exists :param key_name: Key name of the object to be copied :param target_bucket_name: Destination bucket for copied object :param mpu_id: The UploadId returned from the create_multipart_upload call :param part_size: The size parts that the object will be broken into, in bytes. Minimum 5 MiB, Maximum 5 GiB. There is no minimum size for the last part of your multipart upload. :return: part_list for the multipart copy if all parts are copied successfully, else None ''' part_list = [] copy_source = { 'Bucket': source_bucket_name, 'Key': key_name } try: part_counter = 1 object_size = head_object(s3_client, source_bucket_name, key_name) if object_size is not None: object_size = object_size['ContentLength'] while (part_counter - 1) * part_size <object_size: bytes_start = (part_counter - 1) * part_size bytes_end = (part_counter * part_size) - 1 upload_copy_part = s3_client.upload_part_copy ( Bucket = target_bucket_name, CopySource = copy_source, CopySourceRange = f'bytes={bytes_start}-{bytes_end}', Key = key_name, PartNumber = part_counter, UploadId = mpu_id ) part_list.append({'PartNumber': part_counter, 'ETag': upload_copy_part['CopyPartResult']['ETag']}) part_counter += 1 except ClientError as e: logging.error(e) return None return part_list def complete_multipart_upload(s3_client, bucket_name, key_name, mpu_id, part_list): ''' Completes a multipart upload to a directory bucket :param s3_client: boto3 S3 client :param bucket_name: Destination bucket for the multipart upload :param key_name: Key name of the object to be uploaded :param mpu_id: The UploadId returned from the create_multipart_upload call :param part_list: List of uploaded part numbers with associated ETags :return: True if the multipart upload was completed successfully, else False ''' try: s3_client.complete_multipart_upload( Bucket = bucket_name, Key = key_name, UploadId = mpu_id, MultipartUpload = { 'Parts': part_list } ) except ClientError as e: logging.error(e) return False return True if __name__ == '__main__': MB = 1024 ** 2 region = 'us-west-2' source_bucket_name = 'SOURCE_BUCKET_NAME' target_bucket_name = 'TARGET_BUCKET_NAME' key_name = 'KEY_NAME' part_size = 10 * MB s3_client = boto3.client('s3', region_name = region) mpu_id = create_multipart_upload(s3_client, target_bucket_name, key_name) if mpu_id is not None: part_list = multipart_copy_upload(s3_client, source_bucket_name, key_name, target_bucket_name, mpu_id, part_size) if part_list is not None: if complete_multipart_upload(s3_client, target_bucket_name, key_name, mpu_id, part_list): print (f'{key_name} successfully copied through multipart copy from {source_bucket_name} to {target_bucket_name}') else: print (f'Could not copy {key_name} through multipart copy from {source_bucket_name} to {target_bucket_name}')

En el siguiente ejemplo se muestra cómo utilizar una carga multiparte para copiar un objeto mediante programación desde un bucket a un bucket de directorio con la AWS CLI. Para usar el comando, sustituya los marcadores de posición de entrada del usuario con su propia información.

aws s3api upload-part-copy --bucket bucket-base-name--azid--x-s3 --key TARGET_KEY_NAME --copy-source SOURCE_BUCKET_NAME/SOURCE_KEY_NAME --part-number 1 --upload-id "AS_mgt9RaQE9GEaifATue15dAAAAAAAAAAEMAAAAAAAAADQwNzI4MDU0MjUyMBYAAAAAAAAAAA0AAAAAAAAAAAH2AfYAAAAAAAAEBnJ4cxKMAQAAAABiNXpOFVZJ1tZcKWib9YKE1C565_hCkDJ_4AfCap2svg"

Para obtener más información, consulte upload-part-copy en la AWS Command Line Interface.

Enumeración de las cargas multiparte en curso

Para enumerar las cargas multiparte en curso en un bucket de directorio, puede usar los SDK de AWS o la AWS CLI.

SDK for Java 2.x

En los siguientes ejemplos se muestra cómo enumerar las cargas multiparte (incompletas) en curso con el SDK para Java 2.x.

public static void listMultiPartUploads( S3Client s3, String bucketName) { try { ListMultipartUploadsRequest listMultipartUploadsRequest = ListMultipartUploadsRequest.builder() .bucket(bucketName) .build(); ListMultipartUploadsResponse response = s3.listMultipartUploads(listMultipartUploadsRequest); List MultipartUpload uploads = response.uploads(); for (MultipartUpload upload: uploads) { System.out.println("Upload in progress: Key = \"" + upload.key() + "\", id = " + upload.uploadId()); } } catch (S3Exception e) { System.err.println(e.getMessage()); System.exit(1); } }
SDK for Python

En los siguientes ejemplos se muestra cómo enumerar las cargas multiparte (incompletas) en curso con el SDK para Python.

import logging import boto3 from botocore.exceptions import ClientError def list_multipart_uploads(s3_client, bucket_name): ''' List any incomplete multipart uploads in a directory bucket in e specified gion :param s3_client: boto3 S3 client :param bucket_name: Bucket to check for incomplete multipart uploads :return: List of incomplete multipart uploads if there are any, None if not ''' try: response = s3_client.list_multipart_uploads(Bucket = bucket_name) if 'Uploads' in response.keys(): return response['Uploads'] else: return None except ClientError as e: logging.error(e) if __name__ == '__main__': bucket_name = 'BUCKET_NAME' region = 'us-west-2' s3_client = boto3.client('s3', region_name = region) multipart_uploads = list_multipart_uploads(s3_client, bucket_name) if multipart_uploads is not None: print (f'There are {len(multipart_uploads)} ncomplete multipart uploads for {bucket_name}') else: print (f'There are no incomplete multipart uploads for {bucket_name}')

En los siguientes ejemplos se muestra cómo enumerar las cargas multiparte (incompletas) en curso con la AWS CLI. Para usar el comando, sustituya los marcadores de posición de entrada del usuario con su propia información.

aws s3api list-multipart-uploads --bucket bucket-base-name--azid--x-s3

Para obtener más información, consulte list-multipart-uploads en la AWS Command Line Interface.

Enumeración de las partes de una carga multiparte

En los siguientes ejemplos se muestra cómo enumerar las partes de una carga multiparte en un bucket de directorio.

SDK for Java 2.x

En los siguientes ejemplos se muestra cómo enumerar las partes de una carga multiparte en un bucket de directorio con el SDK para Java 2.x.

public static void listMultiPartUploadsParts( S3Client s3, String bucketName, String objKey, String uploadID) { try { ListPartsRequest listPartsRequest = ListPartsRequest.builder() .bucket(bucketName) .uploadId(uploadID) .key(objKey) .build(); ListPartsResponse response = s3.listParts(listPartsRequest); ListPart parts = response.parts(); for (Part part: parts) { System.out.println("Upload in progress: Part number = \"" + part.partNumber() + "\", etag = " + part.eTag()); } } catch (S3Exception e) { System.err.println(e.getMessage()); System.exit(1); } }
SDK for Python

En los siguientes ejemplos se muestra cómo enumerar las partes de una carga multiparte en un bucket de directorio con el SDK para Python.

import logging import boto3 from botocore.exceptions import ClientError def list_parts(s3_client, bucket_name, key_name, upload_id): ''' Lists the parts that have been uploaded for a specific multipart upload to a directory bucket. :param s3_client: boto3 S3 client :param bucket_name: Bucket that multipart uploads parts have been uploaded to :param key_name: Name of the object that has parts uploaded :param upload_id: Multipart upload ID that the parts are associated with :return: List of parts associated with the specified multipart upload, None if there are no parts ''' parts_list = [] next_part_marker = '' continuation_flag = True try: while continuation_flag: if next_part_marker == '': response = s3_client.list_parts( Bucket = bucket_name, Key = key_name, UploadId = upload_id ) else: response = s3_client.list_parts( Bucket = bucket_name, Key = key_name, UploadId = upload_id, NextPartMarker = next_part_marker ) if 'Parts' in response: for part in response['Parts']: parts_list.append(part) if response['IsTruncated']: next_part_marker = response['NextPartNumberMarker'] else: continuation_flag = False else: continuation_flag = False return parts_list except ClientError as e: logging.error(e) return None if __name__ == '__main__': region = 'us-west-2' bucket_name = 'BUCKET_NAME' key_name = 'KEY_NAME' upload_id = 'UPLOAD_ID' s3_client = boto3.client('s3', region_name = region) parts_list = list_parts(s3_client, bucket_name, key_name, upload_id) if parts_list is not None: print (f'{key_name} has {len(parts_list)} parts uploaded to {bucket_name}') else: print (f'There are no multipart uploads with that upload ID for {bucket_name} bucket')

En los siguientes ejemplos se muestra cómo enumerar las partes de una carga multiparte en un bucket de directorio con la AWS CLI. Para usar el comando, sustituya los marcadores de posición de entrada del usuario con su propia información.

aws s3api list-parts --bucket bucket-base-name--azid--x-s3 --key KEY_NAME --upload-id "AS_mgt9RaQE9GEaifATue15dAAAAAAAAAAEMAAAAAAAAADQwNzI4MDU0MjUyMBYAAAAAAAAAAA0AAAAAAAAAAAH2AfYAAAAAAAAEBSD0WBKMAQAAAABneY9yBVsK89iFkvWdQhRCcXohE8RbYtc9QvBOG8tNpA"

Para obtener más información, consulte list-parts en la AWS Command Line Interface.