Utilizzo di caricamenti multiparte con bucket di directory - Amazon Simple Storage Service

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Utilizzo di caricamenti multiparte con bucket di directory

Puoi utilizzare il processo di caricamento in più parti per caricare un singolo oggetto come set di parti. Ciascuna parte è una parte contigua dei dati dell'oggetto. È possibile caricare queste parti dell'oggetto in modo indipendente e in qualsiasi ordine. Se la trasmissione di una parte non riesce, è possibile ritrasmettere tale parte senza influire sulle altre. Una volta caricate tutte le parti dell'oggetto, Amazon S3 le assembla e crea l'oggetto. In generale, quando la dimensione dell'oggetto raggiunge i 100 MB, si consiglia di valutare la possibilità di eseguire caricamenti in più parti anziché caricare l'oggetto in una singola operazione.

Il caricamento in più parti comporta i vantaggi riportati di seguito.

  • Velocità effettiva migliorata: puoi caricare le parti in parallelo per migliorare la velocità effettiva.

  • Ripristino rapido da qualsiasi problema di rete: le dimensioni delle parti più piccole riducono al minimo l'impatto del riavvio di un caricamento non riuscito a causa di un errore di rete.

  • Messa in pausa e ripresa dei caricamenti dell'oggetto: puoi caricare le parti dell'oggetto nel corso del tempo. Dopo aver avviato un caricamento in più parti, non esiste una data di scadenza. È necessario completare o interrompere in modo esplicito il caricamento in più parti.

  • Avvio di un caricamento prima di conoscere la dimensione finale dell'oggetto: puoi caricare un oggetto mentre viene creato.

Ti consigliamo di utilizzare i caricamenti in più parti nei seguenti modi:

  • Se carichi oggetti di grandi dimensioni su una rete stabile a larghezza di banda elevata, utilizza caricamenti in più parti per massimizzare l'uso della larghezza di banda disponibile caricando parti dell'oggetto in parallelo per prestazioni multithread.

  • Se stai caricando su una rete irregolare, utilizza caricamenti in più parti per aumentare la resilienza agli errori di rete evitando il riavvio del caricamento. Quando utilizzi caricamenti in più parti, devi riprovare a caricare solo le parti che sono state interrotte durante il caricamento. Non è necessario riavviare il caricamento dell'oggetto dall'inizio.

Quando utilizzi caricamenti multiparte per caricare oggetti nella classe di storage Amazon S3 Express One Zone nei bucket di directory, il processo di caricamento multiparte è simile al processo di utilizzo del caricamento multiparte per caricare oggetti in bucket generici. Tuttavia, non vi sono alcune differenze importanti.

Per ulteriori informazioni sull'utilizzo di caricamenti in più parti per caricare oggetti su S3 Express One Zone, consulta i seguenti argomenti.

Il processo di caricamento in più parti

Un caricamento in più parti è un processo in tre fasi:

  • Avviate il caricamento.

  • Le parti dell'oggetto vengono caricate.

  • Dopo aver caricato tutte le parti, si completa il caricamento multiparte.

Dopo aver ricevuto la richiesta di caricamento multiparte completa, Amazon S3 costruisce l'oggetto a partire dalle parti caricate e puoi quindi accedere all'oggetto come faresti con qualsiasi altro oggetto nel tuo bucket.

Avvio del caricamento in più parti

Quando invii una richiesta di avvio di un caricamento in più parti, Amazon S3 restituisce una risposta con un ID di caricamento, che è un identificativo univoco per il caricamento in più parti. È necessario includere questo ID di caricamento ogni volta che si caricano o si elencano le parti oppure ogni volta che si completa o si interrompe un caricamento.

Caricamento delle parti

Quando si carica una parte, oltre all'ID di caricamento è necessario specificare il numero della parte. Quando utilizzi un caricamento in più parti con S3 Express One Zone, i codici articolo multiparte devono essere numeri di parte consecutivi. Se tenti di completare una richiesta di caricamento in più parti con numeri di parte non consecutivi, viene generato un errore HTTP 400 Bad Request (Ordine delle parti non valido).

Un numero di parte identifica in modo univoco una parte e la sua posizione nell'oggetto che state caricando. Se caricate una nuova parte utilizzando lo stesso numero di parte di una parte caricata in precedenza, la parte caricata in precedenza viene sovrascritta.

Ogni volta che carichi una parte, Amazon S3 restituisce un'intestazione tag di entità (ETag) nella risposta corrispondente. Per ogni caricamento di parte è necessario registrare il numero della parte e il valore ETag. I valori ETag per tutti i caricamenti di parti di oggetti rimarranno gli stessi, ma a ciascuna parte verrà assegnato un numero di parte diverso. Occorre includere questi valori nella successiva richiesta di complemento del caricamento in più parti.

Amazon S3 esegue automaticamente la crittografa di tutti i nuovi oggetti caricati in un bucket S3. Quando si esegue un caricamento in più parti, se non si specificano le informazioni di crittografia nella richiesta, l'impostazione di crittografia delle parti caricate viene impostata sulla configurazione di crittografia predefinita del bucket di destinazione. La configurazione di crittografia predefinita di un bucket Amazon S3 è sempre abilitata ed è impostata come minimo sulla crittografia lato server con chiavi gestite da Amazon S3 (SSE-S3). Per i bucket di directory, è supportato solo SSE-S3. Per ulteriori informazioni, consulta Crittografia lato server con chiavi gestite da Amazon S3 (SSE-S3).

Completamento del caricamento in più parti

Quando completi un caricamento in più parti, Amazon S3 crea l'oggetto concatenando le parti in ordine crescente in base al numero di parte. Una volta completata la richiesta, le parti non esisteranno più.

La tua richiesta di caricamento multiparte completa deve includere l'ID di caricamento e un elenco di entrambi i numeri di parte e i valori ETag corrispondenti. La risposta di Amazon S3 include un ETag che identifica in modo univoco i dati oggetto combinati. Questo ETag non è un hash MD5 dei dati dell'oggetto.

Elenchi dei caricamenti in più parti

È possibile elencare le parti di un caricamento in più parti specifico o tutti i caricamenti in più parti in corso. L'operazione di creazione dell'elenco delle parti restituisce informazioni sulle parti coinvolte in un caricamento in più parti specifico. Per ogni richiesta di elenco delle parti, Amazon S3 restituisce informazioni sulle parti per il caricamento in più parti specificato, fino a un massimo di 1000 parti. Se nel caricamento in più parti sono presenti più di 1000 parti, è necessario utilizzare la paginazione per recuperare tutte le parti.

L'elenco di parti restituito non include le parti il cui caricamento non è stato completato. L'operazione list multipart uploads (elenco dei caricamenti in più parti) consente di ottenere l'elenco dei caricamenti in più parti in corso.

Un caricamento in più parti in corso è un caricamento avviato, ma non ancora completato o annullato. Ogni richiesta restituisce al massimo 1.000 caricamenti in più parti. Se sono in corso più di 1.000 caricamenti in più parti, è necessario inviare richieste aggiuntive per recuperare i caricamenti rimanenti. Utilizza l'elenco restituito solo per la verifica. Non utilizzarlo per inviare la richiesta complete multipart upload (completamento del caricamento in più parti). Al contrario, mantieni il tuo elenco dei numeri delle parti specificato durante il caricamento delle parti e i valori ETag corrispondenti restituiti da Amazon S3.

Per ulteriori informazioni sulle inserzioni con caricamento multiparte, consulta il riferimento ListPartsall'API di Amazon Simple Storage Service.

Checksum con operazioni di caricamento in più parti

Quando si carica un oggetto, è possibile specificare un algoritmo di checksum per verificare l'integrità dell'oggetto. MD5 non è supportato per i bucket di directory. Puoi specificare uno dei seguenti algoritmi di controllo dell'integrità dei dati tramite Secure Hash Algorithms (SHA) o Cyclic Redundancy Check (CRC):

  • CRC32

  • CRC32C

  • SHA-1

  • SHA-256

Puoi utilizzare l'API REST di Amazon S3 o gli AWS SDK per recuperare il valore del checksum per le singole parti utilizzando o. GetObject HeadObject Se desideri recuperare i valori di checksum per singole parti di caricamenti in più parti ancora in corso, puoi utilizzare ListParts.

Importante

Quando si utilizzano gli algoritmi di checksum precedenti, i numeri di parte multiparte devono utilizzare numeri di parte consecutivi. Se tenti di completare una richiesta di caricamento in più parti con numeri di parte non consecutivi, Amazon S3 genera HTTP 400 Bad Request un errore (Invalid Part Order).

Per ulteriori informazioni sul funzionamento dei checksum con oggetti in più parti, consulta Verifica dell'integrità degli oggetti.

Operazioni simultanee di caricamento in più parti

In un ambiente di sviluppo distribuito, l'applicazione può avviare diversi aggiornamenti sullo stesso oggetto contemporaneamente. Ad esempio, l'applicazione potrebbe avviare diversi caricamenti in più parti utilizzando la stessa chiave oggetto. Per ciascuno di questi caricamenti, l'applicazione può quindi caricare le parti e inviare una richiesta di completamento del caricamento ad Amazon S3 per creare l'oggetto. Per S3 Express One Zone, l'ora di creazione dell'oggetto è la data di completamento del caricamento in più parti.

Nota

Tra l'avvio di un caricamento in più parti e il completamento del caricamento, è possibile che un'altra richiesta ricevuta da Amazon S3 abbia la precedenza. Ad esempio, supponiamo di avviare un caricamento in più parti con il nome della chiave. largevideo.mp4 Prima di completare il caricamento, un'altra operazione elimina la chiave. largevideo.mp4 In tal caso, la risposta completa al caricamento in più parti potrebbe indicare che la creazione dell'oggetto è stata completata correttamente largevideo.mp4 senza che l'utente possa mai vedere l'oggetto.

Importante

Il controllo delle versioni non è supportato per gli oggetti archiviati nei bucket di directory.

Caricamenti e prezzi in più parti

Una volta avviato un caricamento in più parti, Amazon S3 mantiene tutte le parti finché il caricamento non viene completato o interrotto. Per tutta la durata del processo, all'utente vengono fatturati i costi per lo storage, la larghezza di banda e le richieste per questo tipo di caricamento e per le parti associate. Se interrompi il caricamento in più parti, Amazon S3 elimina gli elementi del caricamento e tutte le parti che hai caricato e non ti viene più addebitato alcun costo. Non sono previsti costi di eliminazione anticipata per l'eliminazione di caricamenti multiparte incompleti, indipendentemente dalla classe di archiviazione specificata. Per ulteriori informazioni sui prezzi, consulta la sezione Prezzi di Amazon S3.

Importante

Se la richiesta di caricamento multiparte completa non viene inviata correttamente, le parti dell'oggetto non vengono assemblate e un oggetto non viene creato. Ti viene addebitato tutto lo spazio di storage associato alle parti caricate. È importante completare il caricamento in più parti per creare l'oggetto o interrompere il caricamento in più parti per rimuovere le parti caricate.

Prima di poter eliminare un bucket di directory, devi completare o interrompere tutti i caricamenti multiparte in corso. I bucket di directory non supportano le configurazioni S3 Lifecycle. Se necessario, puoi elencare i caricamenti multiparte attivi, quindi interrompere i caricamenti e quindi eliminare il bucket.

Operazioni e autorizzazioni dell'API di caricamento in più parti

Per consentire l'accesso alle operazioni dell'API di gestione degli oggetti su un bucket di directory, concedi l's3express:CreateSessionautorizzazione in una policy di bucket o in una policy basata sull'identità AWS Identity and Access Management (IAM).

Per eseguire le operazioni di caricamento in più parti, devi disporre delle autorizzazioni necessarie. Puoi utilizzare le bucket policy o le policy basate sull'identità IAM per concedere ai principali IAM le autorizzazioni per eseguire queste operazioni. Nella tabella riportata di seguito sono elencate le autorizzazioni richieste per le varie operazioni di caricamento in più parti.

È possibile identificare l'iniziatore di un caricamento in più parti tramite l'elemento. Initiator Se l'iniziatore è unAccount AWS, questo elemento fornisce le stesse informazioni dell'elemento. Owner Se è un utente IAM, questo elemento fornisce l'ARN e il nome visualizzato dell'utente.

Azione Autorizzazioni richieste

Creazione di un caricamento in più parti

Per creare il caricamento in più parti, devi avere il permesso di eseguire l's3express:CreateSessionazione sul bucket di directory.

Avvia un caricamento in più parti

Per avviare il caricamento in più parti, devi avere il permesso di eseguire l's3express:CreateSessionazione sul bucket di directory.

Carica una parte

Per caricare una parte, devi avere il permesso di eseguire l's3express:CreateSessionazione nel bucket di directory.

Affinché l'iniziatore carichi una parte, il proprietario del bucket deve consentire all'iniziatore di eseguire l's3express:CreateSessionazione sul bucket di directory.

Carica una parte (copia)

Per caricare una parte, devi avere il permesso di eseguire l's3express:CreateSessionazione sul bucket di directory.

Perché l'iniziatore possa caricare una parte di un oggetto, il proprietario del bucket deve consentire all'iniziatore di eseguire l'operazione s3express:CreateSession sull'oggetto.

Completamento del caricamento in più parti

Per completare un caricamento in più parti, è necessario essere autorizzati a eseguire l's3express:CreateSessionazione sul bucket di directory.

Affinché l'iniziatore completi un caricamento in più parti, il proprietario del bucket deve consentire all'iniziatore di eseguire l'azione sull'oggetto. s3express:CreateSession

Interrompere un caricamento in più parti

Per interrompere un caricamento in più parti, devi avere il permesso di eseguire l'azione. s3express:CreateSession

Affinché l'iniziatore possa interrompere un caricamento in più parti, all'iniziatore deve essere concesso l'autorizzazione esplicita all'accesso per eseguire l'azione. s3express:CreateSession

Elenca le parti

Per elencare le parti in un caricamento in più parti, devi avere il permesso di eseguire l's3express:CreateSessionazione sul bucket di directory.

Elenco di caricamenti in più parti in corso

Per elencare i caricamenti multiparte in corso in un bucket, devi avere il permesso di eseguire l'azione su quel bucket. s3:ListBucketMultipartUploads

Supporto operativo tramite API per caricamenti in più parti

Le seguenti sezioni del riferimento all'API di Amazon Simple Storage Service descrivono le operazioni dell'API REST di Amazon S3 per caricamenti multiparte.

Esempi

Per utilizzare un caricamento in più parti per caricare un oggetto su S3 Express One Zone in un bucket di directory, consulta gli esempi seguenti.

Creazione di un caricamento in più parti

Gli esempi seguenti mostrano come creare un caricamento in più parti utilizzando e. AWS SDK for Java 2.x AWS SDK for Python (Boto3)

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

Caricamento delle parti di un caricamento in più parti

Gli esempi seguenti mostrano come suddividere un singolo oggetto in parti e quindi caricare tali parti in un bucket di directory utilizzando SDK for Java 2.x e SDK for Python.

SDK for 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
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

Completamento di un caricamento in più parti

Gli esempi seguenti mostrano come completare un caricamento in più parti utilizzando l'SDK per Java 2.x e l'SDK per Python.

SDK for 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
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}')

Interruzione di un caricamento in più parti

Gli esempi seguenti mostrano come interrompere un caricamento in più parti utilizzando l'SDK per Java 2.x e l'SDK per Python.

SDK for 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
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')

Creazione di un'operazione di copia di caricamento in più parti

Gli esempi seguenti mostrano come utilizzare un caricamento multiparte per copiare a livello di codice un oggetto da un bucket a un altro utilizzando SDK for Java 2.x e SDK for Python.

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 * @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
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}')

Elenco dei caricamenti multiparte in corso

Gli esempi seguenti mostrano come elencare caricamenti multiparte in corso (incompleti) utilizzando l'SDK per Java 2.x e l'SDK per Python.

SDK for 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
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}')

Elencare le parti di un caricamento in più parti

Gli esempi seguenti mostrano come elencare le parti di un caricamento in più parti utilizzando l'SDK per Java 2.x e l'SDK per Python.

SDK for 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
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')