Usar uploads multiparte com buckets de diretório - Amazon Simple Storage Service

Usar uploads multiparte com buckets de diretório

Você pode usar o processo de upload multiparte para fazer upload de um único objeto como um conjunto de partes. Cada parte é uma parte contígua de dados do objeto. O upload dessas partes de objetos pode ser feito de maneira independente e em qualquer ordem. Se a transmissão de alguma parte falhar, você poderá retransmitir essa parte sem afetar outras partes. Depois que todas as partes do objeto forem carregadas, o Amazon S3 montará essas partes e criará o objeto. Geralmente, quando seu objeto alcança 100 MB de tamanho, você deve considerar o uso de multipart uploads em vez de fazer upload do objeto em uma única operação.

Usar o multipart upload fornece as seguintes vantagens:

  • Improved throughput (Throughput aprimorada): você pode carregar as partes em paralelo para melhorar o throughput.

  • Rápida recuperação de qualquer problema de rede: o tamanho menor das partes minimiza o impacto de reiniciar um upload que falhou devido a um erro de rede.

  • Pause and resume object uploads (Pausar e retomar carregamentos de objetos): você pode carregar as partes do objeto ao longo do tempo. Um upload multiparte iniciado não tem data de expiração. Você deve concluir ou anular explicitamente o upload multiparte.

  • Begin an upload before you know the final object size (Começar um carregamento antes de saber o tamanho final do objeto): você pode carregar um objeto à medida que ele é criado.

Recomendamos que você use uploads multiparte das seguintes maneiras:

  • Se você estiver fazendo upload de objetos grandes em uma rede de banda larga estável, use os uploads multiparte para maximizar o uso da banda larga disponível, fazendo upload das partes do objeto em paralelo para performance com vários threads.

  • Se você estiver fazendo upload em uma rede lenta, use os uploads multiparte para aumentar a resiliência dos erros de rede, evitando reinícios de upload. Ao usar os uploads multiparte, tente fazer upload novamente apenas das partes que foram interrompidas durante o upload. Você não precisa reiniciar o upload do seu objeto do começo.

Quando você usa uploads multiparte para fazer upload de objetos para a classe de armazenamento Amazon S3 Express One Zone em buckets de diretório, o processo de upload multiparte é semelhante ao processo de uso de um upload multiparte para fazer upload de objetos em buckets de uso geral. No entanto, há algumas diferenças importantes.

Para obter mais informações sobre como usar uploads multiparte para fazer upload de objetos na classe S3 Express One Zone, consulte os tópicos a seguir.

O processo de upload multiparte

Um upload multiparte é um processo de três etapas:

  • Você inicia o upload.

  • Você faz upload das partes do objeto.

  • Depois de fazer upload de todas as partes, você conclui o upload multiparte.

Ao receber a solicitação de conclusão do upload multiparte, o Amazon S3 cria o objeto com base nas partes carregadas, e você poderá acessar o objeto como qualquer outro objeto no bucket.

Iniciação do multipart upload

Quando você envia uma solicitação para iniciar um multipart upload, o Amazon S3 retorna uma resposta com um ID de upload, que é um identificador exclusivo do seu multipart upload. Você deve incluir esse ID de upload sempre que fizer upload de partes, listar as partes, concluir um upload ou anular um upload.

Carregamento de partes

Ao fazer upload de uma parte, além do ID de upload, você deve especificar um número de parte. Ao usar um upload multiparte com a classe S3 Express One Zone, os números do upload multiparte devem ser consecutivos. Se você tentar concluir uma solicitação de upload multiparte com números de parte não consecutivos, será gerado um erro HTTP 400 Bad Request (ordem das partes inválida).

Um número de parte identifica de maneira única uma parte e sua posição no objeto que está sendo carregado. Se você fizer upload de uma nova parte usando o mesmo número da parte anteriormente carregada, a parte anteriormente carregada será substituída.

Sempre que você carregar uma parte, o Amazon S3 retornará um cabeçalho entity tag (ETag) etiqueta de entidade (ETag) na resposta. Para cada upload de parte, você deve registrar o número de parte e o valor de ETag. Os valores de ETag para todos os uploads de partes do objeto permanecerá o mesmo, mas cada parte receberá um número de parte diferente. Você tem que incluir esses valores na solicitação subsequente para concluir o multipart upload.

O Amazon S3 criptografa automaticamente todos os novos objetos que são carregados em um bucket do S3. Ao realizar um carregamento multiparte, se você não especificar informações de criptografia na solicitação, a configuração de criptografia das partes carregadas será definida como a configuração de criptografia padrão do bucket de destino. A configuração de criptografia padrão de um bucket do Amazon S3 está sempre habilitada e, no mínimo, definida como criptografia do lado do servidor com chaves gerenciadas pelo Amazon S3 (SSE-S3). Buckets de diretório só são compatíveis com SSE-S3. Para ter mais informações, consulte Criptografia do lado do servidor com chaves gerenciadas pelo Amazon S3 (SSE-S3).

Conclusão de carregamento fracionado

Quando você concluir um upload multiparte, o Amazon S3 criará o objeto concatenando as partes em ordem crescente com base no número da parte. Depois de uma solicitação de conclusão bem-sucedida, as partes não existem mais.

Sua solicitação concluir upload multiparte deve incluir o ID de upload e uma lista dos números das partes e dos valores de ETag correspondentes. A resposta do Amazon S3 inclui um ETag que identifica exclusivamente os dados do objeto combinados. Esse ETag não é um hash MD5 dos dados do objeto.

Listagens de carregamento fracionado

Você pode listar as partes de um multipart upload específico ou de todos os multipart uploads em andamento. A operação de listagem de partes retorna as informações das partes que você fez upload em um multipart upload específico. Para cada solicitação de listagem de partes, o Amazon S3 retorna informações das partes do multipart upload especificado, até no máximo 1.000 partes. Se houver mais de 1.000 partes no carregamento multiparte, você deverá usar a paginação para recuperar todas as partes.

A lista de partes retornada não inclui aquelas cujo upload não foi concluído. Usando a operação list multipart uploads (listar carregamentos fracionados), você pode obter uma lista daqueles que estão em andamento.

Um multipart upload em andamento é um upload que você iniciou, mas que ainda não concluiu ou anulou. Cada solicitação retorna no máximo 1.000 multipart uploads. Se houver mais de 1.000 carregamento fracionados em andamento, você precisará enviar solicitações adicionais para recuperar os carregamento fracionados restantes. Use a listagem retornada apenas para verificação. Não use o resultado dessa listagem ao enviar uma solicitação complete multipart upload (concluir carregamento fracionado). Em vez disso, mantenha sua própria lista de números de parte que você especificou ao carregar as partes e os valores correspondentes de ETag que o Amazon S3 retorna.

Para obter mais informações sobre listagens de upload multiparte, consulte ListParts na Referência da API do Amazon Simple Storage Service.

Somas de verificação com operações de carregamento fracionado

Ao fazer upload de um objeto, você pode especificar um algoritmo de soma de verificação para verificar a integridade dele. O MD5 não é compatível com buckets de diretório. Você pode especificar um dos seguintes algoritmos de verificação de integridade de dados de hash seguro (SHA) ou de verificação de redundância cíclica (CRC):

  • CRC32

  • CRC32C

  • SHA-1

  • SHA-256

Você pode usar a API REST do Amazon S3 ou os AWS SDKs para recuperar o valor da soma de verificação para partes específicas usando GetObject ou HeadObject. Se você quiser recuperar os valores da soma de verificação para partes individuais de carregamentos fracionados ainda em andamento, você pode usar ListParts.

Importante

Ao usar os algoritmos de soma de verificação anteriores, os números de parte do upload multiparte devem ser consecutivos. Se você tentar concluir uma solicitação de upload multiparte com números de parte não consecutivos, o Amazon S3 gerará um erro HTTP 400 Bad Request (ordem das partes inválida).

Para obter mais informações sobre como as somas de verificação funcionam com objetos fracionados, consulte Verificar a integridade do objeto.

Operações simultâneas de carregamento fracionado

Em um ambiente de desenvolvimento distribuído, a aplicação pode iniciar várias atualizações no mesmo objeto ao mesmo tempo. Por exemplo, a aplicação pode iniciar vários uploads multiparte usando a mesma chave de objeto. Para cada um desses uploads, sua aplicação pode fazer upload das partes e enviar uma solicitação de conclusão de upload ao Amazon S3 para criar o objeto. Para a classe S3 Express One Zone, a hora de criação do objeto é a data de conclusão do carregamento multiparte.

Importante

O versionamento não é compatível com objetos armazenados em buckets de diretório.

Uploads multiparte e preços

Depois que você iniciar um carregamento multiparte, o Amazon S3 reterá todas as partes até você concluir ou anular o upload. Durante todo o ciclo de vida, você será cobrado por armazenamento, largura de banda e solicitações desse multipart upload e das partes associadas. Se você anular o upload multiparte, o Amazon S3 excluirá os artefatos de upload e todas as partes carregadas, o que significa que não serão mais cobrados de você. Não há cobrança de exclusão antecipada pela exclusão de uploads multiparte incompletos, independentemente da classe de armazenamento especificada. Para obter mais informações sobre a definição de preços, consulte Definição de preços do Amazon S3.

Importante

Se a solicitação de conclusão do upload multiparte não for enviada com sucesso, as partes do objeto não serão montadas e o objeto não será criado. Você é cobrado por todo o armazenamento associado a partes enviadas por upload. É importante que você conclua o upload multiparte para que o objeto seja criado ou anule o upload multiparte para remover todas as partes carregadas.

Antes de excluir um bucket de diretório, é necessário concluir ou anular todos os uploads multiparte em andamento. Os buckets de diretório não oferecem suporte às configurações da funcionalidade Ciclo de Vida do S3. Se necessário, você pode listar os uploads multiparte ativos, depois anulá-los e excluir o bucket.

Operações de API de upload multiparte e permissões

Para permitir o acesso às operações de API de gerenciamento de objetos em um bucket de diretório, conceda a permissão s3express:CreateSession em uma política de bucket ou em uma política baseada em identidade do AWS Identity and Access Management (IAM).

Você deve ter as permissões necessárias para usar as operações do multipart upload. Você pode usar políticas de bucket ou políticas baseadas em identidade do IAM para conceder permissões a entidades principais do IAM para realizar essas operações. A tabela a seguir lista as permissões necessárias para diversas operações de carregamento multiparte.

Você pode identificar o iniciador de um upload multiparte por meio do elemento Initiator. Se o iniciador for uma Conta da AWS, esse elemento fornecerá as mesmas informações que o elemento Owner. Se o iniciador for um usuário do IAM, esse elemento fornecerá o ARN e o nome da exibição do usuário.

Ação Permissões obrigatórias

Criar um carregamento fracionado

Para criar um upload multiparte, você deve ter permissão para realizar a ação s3express:CreateSession em um bucket de diretório.

Iniciar um upload multiparte

Para iniciar o upload multiparte, você deve ter permissão para realizar a ação s3express:CreateSession no bucket de diretório.

Fazer upload de uma parte

Para fazer upload de uma parte, você deve ter permissão para realizar a ação s3express:CreateSession em um bucket de diretório.

Para que o iniciador possa fazer upload de uma parte, o proprietário do bucket deve permitir que o iniciador realize a ação s3express:CreateSession em um bucket de diretório.

Fazer upload de uma parte (cópia)

Para fazer upload de uma parte, você deve ter permissão para realizar a ação s3express:CreateSession em um bucket de diretório.

Para iniciador fazer upload de uma parte para um objeto, o proprietário do bucket deve permitir que o iniciador realize a ação s3express:CreateSession no objeto.

Concluir um carregamento fracionado

Para concluir um upload multiparte, você deve ter permissão para realizar a ação s3express:CreateSession no bucket de diretório.

Para que o iniciador possa concluir um upload multiparte, o proprietário do bucket deve permitir que o iniciador realize a ação s3express:CreateSession no objeto.

Anular um multipart upload

Para anular um upload multiparte, você deve ter permissão para realizar a ação s3express:CreateSession.

Para que o iniciador anule um upload multiparte, ele deve receber permissão explícita para realizar a ação s3express:CreateSession.

Listar partes

Para listar as partes de um upload multiparte, você deve ter permissão para realizar a ação s3express:CreateSession no bucket de diretório.

Listar carregamentos fracionados em andamento

Para listar os uploads multiparte em andamento em um bucket, você deve ter permissão para realizar a ação s3:ListBucketMultipartUploads nesse bucket.

Suporte às operações de API para uploads multiparte

As seções a seguir na Referência da API do Amazon Simple Storage Service descrevem a API REST do Amazon S3 para uploads multiparte.

Exemplos

Para usar um upload multiparte a fim de fazer upload de um objeto na classe S3 Express One Zone em um bucket de diretório, consulte os exemplos a seguir.

Criar um carregamento multiparte

Os exemplos a seguir mostram como criar um carregamento fracionado.

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

Este exemplo mostra como criar um carregamento fracionado em um bucket de diretório usando a AWS CLI. Esse comando inicia um carregamento fracionado no bucket de diretório bucket-base-name--azid--x-s3 para o objeto KEY_NAME. Para usar o comando, substitua os espaços reservados para entrada do usuário por suas próprias informações.

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

Para obter mais informações, consulte create-multipart-upload na AWS Command Line Interface.

Fazer upload das partes de um upload multiparte

Os exemplos a seguir mostram como carregar partes de um carregamento fracionado.

SDK for Java 2.x

O exemplo a seguir mostra como dividir um único objeto em partes e carregá-las em um bucket de diretório usando o 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

O exemplo a seguir mostra como dividir um único objeto em partes e carregá-las em um bucket de diretório usando o 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

O exemplo a seguir mostra como dividir um único objeto em partes e carregá-las em um bucket de diretório usando a AWS CLI. Para usar o comando, substitua os espaços reservados para entrada do usuário por suas próprias informações.

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 obter mais informações, consulte upload-part na AWS Command Line Interface.

Concluir um carregamento multiparte

Os exemplos a seguir mostram como concluir um carregamento fracionado.

SDK for Java 2.x

Os exemplos a seguir mostram como concluir um carregamento fracionado usando o 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

Os exemplos a seguir mostram como concluir um carregamento fracionado usando o 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}')

Este exemplo mostra como concluir um carregamento fracionado em um bucket de diretório usando a AWS CLI. Para usar o comando, substitua os espaços reservados para entrada do usuário por suas próprias informações.

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 exemplo usa uma estrutura JSON que descreve quais partes do carregamento fracionado devem ser reagrupadas no arquivo completo. Neste exemplo, o prefixo file:// é usado para carregar a estrutura JSON de um arquivo na pasta local chamada parts.

parts.json:

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

Para obter mais informações, consulte complete-multipart-upload na AWS Command Line Interface.

Abortar um multipart upload

Os exemplos a seguir mostram como interromper um carregamento fracionado.

SDK for Java 2.x

O exemplo a seguir mostra como interromper um carregamento fracionado usando o 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

O exemplo a seguir mostra como interromper um carregamento fracionado usando o 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')

O exemplo a seguir mostra como interromper um carregamento fracionado usando a AWS CLI. Para usar o comando, substitua os espaços reservados para entrada do usuário por suas próprias informações.

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

Para obter mais informações, consulte abort-multipart-upload na AWS Command Line Interface.

Criar uma operação de cópia de carregamento multiparte

Os exemplos a seguir mostram como copiar objetos de um bucket para outro usando um carregamento fracionado.

SDK for Java 2.x

O exemplo a seguir mostra como usar um carregamento fracionado para copiar um objeto de um bucket para outro de forma programática usando o 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

O exemplo a seguir mostra como usar um carregamento fracionado para copiar um objeto de um bucket para outro de forma programática usando o 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}')

O exemplo a seguir mostra como usar um carregamento fracionado para copiar um objeto de um bucket para outro de forma programática usando a AWS CLI. Para usar o comando, substitua os espaços reservados para entrada do usuário por suas próprias informações.

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 obter mais informações, consulte upload-part-copy na AWS Command Line Interface.

Listar os uploads multiparte em andamento

Para listar carregamentos fracionados em andamento em um bucket de diretório, é possível usar os SDKs da AWS ou a AWS CLI.

SDK for Java 2.x

Os exemplos a seguir mostram como listar carregamentos fracionados em andamento (incompletos) usando o 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

Os exemplos a seguir mostram como listar carregamentos fracionados em andamento (incompletos) usando o 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}')

Os exemplos a seguir mostram como listar carregamentos fracionados em andamento (incompletos) usando a AWS CLI. Para usar o comando, substitua os espaços reservados para entrada do usuário por suas próprias informações.

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

Para obter mais informações, consulte list-multipart-uploads na AWS Command Line Interface.

Listar as partes de um upload multiparte

Os exemplos a seguir mostram como listar partes de um carregamento fracionado em um bucket de diretório.

SDK for Java 2.x

Os exemplos a seguir mostram como listar partes de um carregamento fracionado em um bucket de diretório usando o 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

Os exemplos a seguir mostram como listar partes de um carregamento fracionado em um bucket de diretório usando o 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')

Os exemplos a seguir mostram como listar partes de um carregamento fracionado em um bucket de diretório usando a AWS CLI. Para usar o comando, substitua os espaços reservados para entrada do usuário por suas próprias informações.

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

Para obter mais informações, consulte list-parts na AWS Command Line Interface.