Ao enviar arquivos grandes (maiores que 5 GB) para o OSS, interrupções de rede ou falhas no programa podem causar erros. O upload multipart divide arquivos grandes em partes menores para envio simultâneo, aumentando a velocidade e a resiliência. Após o envio de todas as partes, chame a operação CompleteMultipartUpload para combiná-las em um objeto completo.
Observações
Este tópico utiliza o endpoint público da região China (Hangzhou). Para acessar o OSS a partir de outros serviços da Alibaba Cloud na mesma região, use um endpoint interno. Para mais informações sobre regiões e endpoints do OSS, consulte Regiões e endpoints.
As credenciais de acesso neste tópico são obtidas de variáveis de ambiente. Para saber como configurar credenciais de acesso, consulte Configurar credenciais de acesso (Python SDK V1).
Este tópico demonstra a criação de uma instância OSSClient com um endpoint do OSS. Para configurações alternativas, como uso de domínio personalizado ou autenticação com credenciais do Security Token Service (STS), consulte Inicialização.
O processo de upload multipart (InitiateMultipartUpload, UploadPart e CompleteMultipartUpload) exige a permissão
oss:PutObject. Consulte Conceder permissões personalizadas a um usuário RAM.
Processo de upload multipart
O upload multipart consiste em três etapas:
-
Inicialize um evento de upload multipart.
Chame bucket.init_multipart_upload para obter um uploadId globalmente único.
-
Envie as partes.
Chame bucket.upload_part para enviar cada parte.
NotaPara um determinado uploadId, o número da parte identifica sua posição no arquivo. O envio de uma parte com o mesmo número sobrescreve os dados existentes.
O OSS retorna o hash MD5 dos dados da parte recebida no cabeçalho de resposta ETag.
O OSS compara o hash MD5 dos dados enviados com o hash MD5 calculado pelo SDK. Em caso de divergência, o sistema retorna o código de erro InvalidDigest.
-
Conclua o upload multipart.
Após o envio de todas as partes, chame bucket.complete_multipart_upload para combiná-las em um objeto completo.
Exemplos completos de upload multipart
Combine as partes enviadas em um objeto completo de duas formas:
-
Combinação de partes mediante passagem das informações no corpo da requisição
# -*- coding: utf-8 -*- import os from oss2 import SizedFileAdapter, determine_part_size from oss2.models import PartInfo import oss2 from oss2.credentials import EnvironmentVariableCredentialsProvider # Obtain access credentials from environment variables. Before running this code, make sure you have set the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables. auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider()) # Set Endpoint to the endpoint of the region where the bucket is located. For example, for a bucket in the China (Hangzhou) region, set Endpoint to https://oss-cn-hangzhou.aliyuncs.com. endpoint = "https://oss-cn-hangzhou.aliyuncs.com" # Set region to the region ID that corresponds to the endpoint, for example, cn-hangzhou. Note: This parameter is required for SignatureV4. region = "cn-hangzhou" # Set yourBucketName to the name of your bucket. bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region) # Set key to the full path of the object. The path cannot include the bucket name. Example: exampledir/exampleobject.txt. key = 'exampledir/exampleobject.txt' # Set filename to the full path of the local file. Example: D:\\localpath\\examplefile.txt. filename = 'D:\\localpath\\examplefile.txt' total_size = os.path.getsize(filename) # The determine_part_size method determines the part size. The minimum part size is 100 KB, and the maximum is 5 GB. The last part can be smaller than 100 KB. This example sets the part size to 1 MB. part_size = determine_part_size(total_size, preferred_size=1 * 1024 * 1024) # Initialize the multipart upload. # To set headers when you initialize the multipart upload, set the relevant headers in init_multipart_upload as shown below. # headers = dict() # Specify the web page caching behavior for the object. # headers['Cache-Control'] = 'no-cache' # Specify the name of the object when it is downloaded. # headers['Content-Disposition'] = 'oss_MultipartUpload.txt' # Specify the expiration time in milliseconds. # headers['Expires'] = '1000' # Specify whether to overwrite an object that has the same name when you initialize the multipart upload. Here, it is set to true, which prohibits overwriting. # headers['x-oss-forbid-overwrite'] = 'true' # Specify the server-side encryption method for each part of the object. # headers[OSS_SERVER_SIDE_ENCRYPTION] = SERVER_SIDE_ENCRYPTION_KMS # Specify the encryption algorithm for the object. If this is not specified, AES256 is used. # headers[OSS_SERVER_SIDE_DATA_ENCRYPTION] = SERVER_SIDE_ENCRYPTION_KMS # The customer master key (CMK) managed by KMS. # headers[OSS_SERVER_SIDE_ENCRYPTION_KEY_ID] = '9468da86-3509-4f8d-a61e-6eab1eac****' # Specify the storage class of the object. # headers['x-oss-storage-class'] = oss2.BUCKET_STORAGE_CLASS_STANDARD # Specify object tags. You can set multiple tags. # headers[OSS_OBJECT_TAGGING] = 'k1=v1&k2=v2&k3=v3' # upload_id = bucket.init_multipart_upload(key, headers=headers).upload_id upload_id = bucket.init_multipart_upload(key).upload_id # Use the upload_id to cancel the multipart upload event or list uploaded parts. # To cancel a multipart upload event by uploadId, get the uploadId after you call InitiateMultipartUpload. # To list uploaded parts by uploadId, get the uploadId after you call InitiateMultipartUpload and before you call CompleteMultipartUpload. # print("UploadID:", upload_id) parts = [] # Upload parts one by one. with open(filename, 'rb') as fileobj: part_number = 1 offset = 0 while offset < total_size: num_to_upload = min(part_size, total_size - offset) # The SizedFileAdapter(fileobj, size) method generates a new file object and recalculates the starting position for appending. result = bucket.upload_part(key, upload_id, part_number, SizedFileAdapter(fileobj, num_to_upload)) parts.append(PartInfo(part_number, result.etag)) offset += num_to_upload part_number += 1 # Complete the multipart upload. # To set headers when you complete the multipart upload, see the following sample code. headers = dict() # Set the access control list (ACL) for the file. Here, it is set to OBJECT_ACL_PRIVATE, which means private. # headers["x-oss-object-acl"] = oss2.OBJECT_ACL_PRIVATE bucket.complete_multipart_upload(key, upload_id, parts, headers=headers) # bucket.complete_multipart_upload(key, upload_id, parts)ImportanteSe as condições de rede forem favoráveis, aumente o tamanho da parte. Caso contrário, diminua-o.
-
Combinação de partes mediante listagem dos dados no servidor
NotaAntes de usar este método, certifique-se de ter enviado várias partes com o upload_id especificado no código a seguir.
# -*- coding: utf-8 -*- import oss2 from oss2.credentials import EnvironmentVariableCredentialsProvider # Obtain access credentials from environment variables. Before running this code, make sure you have set the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables. auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider()) # Set Endpoint to the endpoint of the region where the bucket is located. For example, for a bucket in the China (Hangzhou) region, set Endpoint to https://oss-cn-hangzhou.aliyuncs.com. endpoint = "https://oss-cn-hangzhou.aliyuncs.com" # Set region to the region ID that corresponds to the endpoint, for example, cn-hangzhou. Note: This parameter is required for SignatureV4. region = "cn-hangzhou" # Set yourBucketName to the name of your bucket. bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region) # Set key to the full path of the object. The path cannot include the bucket name. Example: exampledir/exampleobject.txt. key = 'exampledir/exampleobject.txt' # Set filename to the full path of the local file. Example: D:\\localpath\\examplefile.txt. filename = 'D:\\localpath\\examplefile.txt' # Set upload_id. Get the upload_id after you call InitiateMultipartUpload and before you call CompleteMultipartUpload. upload_id = '0004B9894A22E5B1888A1E29F823****' # Complete the multipart upload. # To set the file ACL when you complete the multipart upload, set the relevant headers in the complete_multipart_upload function as shown below. headers = dict() # headers["x-oss-object-acl"] = oss2.OBJECT_ACL_PRIVATE # If you set x-oss-complete-all to yes, OSS lists all parts that have been uploaded with the current uploadId, sorts them by part number, and then runs the CompleteMultipartUpload operation. # If you set x-oss-complete-all to yes, you cannot specify a body. Otherwise, an error is returned. headers["x-oss-complete-all"] = 'yes' bucket.complete_multipart_upload(key, upload_id, None, headers=headers)
Cancele um evento de upload multipart
Chame bucket.abort_multipart_upload para cancelar um upload multipart. Após o cancelamento, o uploadId torna-se inválido e as partes enviadas são excluídas.
# -*- coding: utf-8 -*-
import os
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# Obtain access credentials from environment variables. Before running this code, make sure you have set the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables.
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# Set Endpoint to the endpoint of the region where the bucket is located. For example, for a bucket in the China (Hangzhou) region, set Endpoint to https://oss-cn-hangzhou.aliyuncs.com.
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# Set region to the region ID that corresponds to the endpoint, for example, cn-hangzhou. Note: This parameter is required for SignatureV4.
region = "cn-hangzhou"
# Set yourBucketName to the name of your bucket.
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
# Set key to the full path of the object. The path cannot include the bucket name. Example: exampledir/exampleobject.txt.
key = 'exampledir/exampleobject.txt'
# Set upload_id. The upload_id is returned after you call InitiateMultipartUpload.
upload_id = 'yourUploadId'
# Cancel the multipart upload event for the specified upload_id. The uploaded parts will be deleted.
bucket.abort_multipart_upload(key, upload_id)
Listar partes enviadas
O código a seguir lista as partes enviadas:
# -*- coding: utf-8 -*-
import os
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# Obtain access credentials from environment variables. Before running this code, make sure you have set the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables.
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# Set Endpoint to the endpoint of the region where the bucket is located. For example, for a bucket in the China (Hangzhou) region, set Endpoint to https://oss-cn-hangzhou.aliyuncs.com.
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# Set region to the region ID that corresponds to the endpoint, for example, cn-hangzhou. Note: This parameter is required for SignatureV4.
region = "cn-hangzhou"
# Set yourBucketName to the name of your bucket.
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
# Set key to the full path of the object. The path cannot include the bucket name. Example: exampledir/exampleobject.txt.
key = 'exampledir/exampleobject.txt'
# Set upload_id. Get the upload_id after you call InitiateMultipartUpload and before you call CompleteMultipartUpload.
upload_id = 'yourUploadId'
# List information about the parts uploaded with the specified upload_id.
for part_info in oss2.PartIterator(bucket, key, upload_id):
print('part_number:', part_info.part_number)
print('etag:', part_info.etag)
print('size:', part_info.size)
Listar eventos de upload multipart
-
Listar eventos de upload multipart de um objeto específico
O código a seguir lista os eventos de upload multipart de um objeto específico:
# -*- coding: utf-8 -*- import os import oss2 from oss2.credentials import EnvironmentVariableCredentialsProvider # Obtain access credentials from environment variables. Before running this code, make sure you have set the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables. auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider()) # Set Endpoint to the endpoint of the region where the bucket is located. For example, for a bucket in the China (Hangzhou) region, set Endpoint to https://oss-cn-hangzhou.aliyuncs.com. endpoint = "https://oss-cn-hangzhou.aliyuncs.com" # Set region to the region ID that corresponds to the endpoint, for example, cn-hangzhou. Note: This parameter is required for SignatureV4. region = "cn-hangzhou" # Set yourBucketName to the name of your bucket. bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region) # Set key to the full path of the object. The path cannot include the bucket name. Example: exampledir/exampleobject.txt. key = 'exampledir/exampleobject.txt' # List all multipart upload events for the object. Each call to init_multipart_upload for the same object returns a different upload_id. # Each upload_id corresponds to one multipart upload event. for upload_info in oss2.ObjectUploadIterator(bucket, key): print('key:', upload_info.key) print('upload_id:', upload_info.upload_id) -
Listar todos os eventos de upload multipart em um bucket
O código a seguir lista todos os eventos de upload multipart em um bucket:
# -*- coding: utf-8 -*- import os import oss2 from oss2.credentials import EnvironmentVariableCredentialsProvider # An AccessKey pair of an Alibaba Cloud account has permissions on all API operations. This poses a high security risk. We strongly recommend that you create and use a RAM user for API access or routine O&M. To create a RAM user, log on to the RAM console. auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider()) # Set Endpoint to the endpoint of the region where the bucket is located. For example, for a bucket in the China (Hangzhou) region, set Endpoint to https://oss-cn-hangzhou.aliyuncs.com. endpoint = "https://oss-cn-hangzhou.aliyuncs.com" # Set region to the region ID that corresponds to the endpoint, for example, cn-hangzhou. Note: This parameter is required for SignatureV4. region = "cn-hangzhou" # Set yourBucketName to the name of your bucket. bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region) # List all multipart upload events in the bucket. for upload_info in oss2.MultipartUploadIterator(bucket): print('key:', upload_info.key) print('upload_id:', upload_info.upload_id) -
Listar eventos de upload multipart por prefixo
O código a seguir lista eventos de upload multipart de objetos com um prefixo específico:
# -*- coding: utf-8 -*- import os import oss2 from oss2.credentials import EnvironmentVariableCredentialsProvider # An AccessKey pair of an Alibaba Cloud account has permissions on all API operations. This poses a high security risk. We strongly recommend that you create and use a RAM user for API access or routine O&M. To create a RAM user, log on to the RAM console. auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider()) # Set Endpoint to the endpoint of the region where the bucket is located. For example, for a bucket in the China (Hangzhou) region, set Endpoint to https://oss-cn-hangzhou.aliyuncs.com. endpoint = "https://oss-cn-hangzhou.aliyuncs.com" # Set region to the region ID that corresponds to the endpoint, for example, cn-hangzhou. Note: This parameter is required for SignatureV4. region = "cn-hangzhou" # Set yourBucketName to the name of your bucket. bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region) # List multipart upload events for objects in the bucket that have the 'test' prefix. for upload_info in oss2.MultipartUploadIterator(bucket, prefix='test'): print('key:', upload_info.key) print('upload_id:', upload_info.upload_id)
Perguntas frequentes
Como excluir partes?
Se um upload multipart for interrompido sem a chamada de AbortMultipartUpload, as partes enviadas permanecerão no bucket e gerarão custos de armazenamento. Exclua-as de uma das seguintes maneiras:
Exclua partes manualmente. Consulte Excluir partes.
Exclua partes automaticamente com regras de ciclo de vida. Consulte Exemplos de configuração de ciclo de vida.
Referências
-
Um upload multipart envolve três operações de API:
Inicializar um upload multipart: InitiateMultipartUpload.
Enviar uma parte: UploadPart.
Concluir um upload multipart: CompleteMultipartUpload.
Cancelar um upload multipart: AbortMultipartUpload.
Listar partes enviadas: ListParts.
Listar uploads multipart em andamento: ListMultipartUploads.