Загрузка больших файлов в хранилище BLOB-объектов Azure, исключение - PullRequest
0 голосов
/ 02 марта 2019

У меня есть сценарий для загрузки резервных копий баз данных в хранилище BLOB-объектов Azure с помощью службы Windows.Он работает для диапазона файлов bak между 300-500 МБ, но если размер превышает 700 МБ до 1 ГБ или более.Это заняло больше часа, а затем выдало исключение.

Пожалуйста, проверьте код ниже, дайте мне знать, что я делаю неправильно и каков эффективный способ загрузки файлов большого размера в хранилище BLOB-объектов.Я попробовал эти два метода.

public static void UploadFile(AzureOperationHelper azureOperationHelper)
{
    CloudBlobContainer blobContainer = CreateCloudBlobContainer(tenantId, applicationId,
                                       clientSecret, azureOperationHelper.storageAccountName, azureOperationHelper.containerName,
                                       azureOperationHelper.storageEndPoint);
    blobContainer.CreateIfNotExists();


    var writeOptions = new BlobRequestOptions()
    {
        SingleBlobUploadThresholdInBytes = 50 * 1024 * 1024,//maximum for 64MB,32MB by default  
        ParallelOperationThreadCount = 12,
    };

    CloudBlockBlob blob = blobContainer.GetBlockBlobReference(azureOperationHelper.blobName);
    //blob.UploadFromFile(azureOperationHelper.srcPath);            
    blob.UploadFromFile(azureOperationHelper.srcPath, options: writeOptions);
}

public static void UploadFileStream(AzureOperationHelper azureOperationHelper)
{
    CloudBlobContainer blobContainer = CreateCloudBlobContainer(tenantId, applicationId,
                                       clientSecret, azureOperationHelper.storageAccountName, azureOperationHelper.containerName,
                                       azureOperationHelper.storageEndPoint);
    blobContainer.CreateIfNotExists();
    CloudBlockBlob blob = blobContainer.GetBlockBlobReference(azureOperationHelper.blobName);

    //byte[] contents = File.ReadAllBytes(azureOperationHelper.srcPath);
    //var writeOptions = new BlobRequestOptions()
    //{
    //    SingleBlobUploadThresholdInBytes = 50 * 1024 * 1024,//maximum for 64MB,32MB by default  
    //    ParallelOperationThreadCount = 12,        
    //};
    //blob.UploadFromByteArray(contents, 0, contents.Length, AccessCondition.GenerateIfNotExistsCondition(), options: writeOptions);
    blob.StreamWriteSizeInBytes = 100 * 1024 * 1024; //100 MB
    blob.UploadFromFile(string.Format(azureOperationHelper.srcPath));
    //using (var fs = new FileStream(azureOperationHelper.srcPath, FileMode.Open))
    //{
    //    blob.UploadFromStream(fs);
    //}            

}

Ниже приведены исключения, которые я получил.

Microsoft.WindowsAzure.Storage.StorageException: удаленный сервер возвратил ошибку: (403)Запрещено.---> System.Net.WebException: удаленный сервер возвратил ошибку: (403) Запрещено.в Microsoft.WindowsAzure.Storage.Shared.Protocol.HttpResponseParsers.ProcessExpectedStatusCodeNoException [T] (HttpStatusCode ОжидаемыйStatusCode, HttpStatusCode actualStatusCode, T retVal, StorageCommandBase`1 * 101 * * 101 * * 101 1012, исключение 1011) исключение 1011, исключение: 1011, исключение 1011, исключение: 1011, исключение: 1011, исключение: 1011, исключение: 1010 исключений, исключений: 1011, исключая исключительную ситуацию, 1011 1011, исключение: 1011, исключая исключительную ситуацию - 1011 * 1012, исключение: 1011 * 1011, исключение: 1011, исключение: 1011, исключ.Microsoft.WindowsAzure.Storage.StorageException: клиент не смог завершить операцию в течение указанного времени ожидания.---> System.TimeoutException: клиент не смог завершить операцию в течение указанного времени ожидания.

1 Ответ

0 голосов
/ 04 марта 2019

Пожалуйста, код ниже, он хорошо работает на моей стороне (около 2 ГБ файла, занимает около 10 минут для завершения загрузки):

public string UploadFile(string sourceFilePath)
{
    try
    {
        string storageAccountConnectionString = "AZURE_CONNECTION_STRING";
        CloudStorageAccount StorageAccount = CloudStorageAccount.Parse(storageAccountConnectionString);
        CloudBlobClient BlobClient = StorageAccount.CreateCloudBlobClient();
        CloudBlobContainer Container = BlobClient.GetContainerReference("container-name");
        Container.CreateIfNotExists();
        CloudBlockBlob blob = Container.GetBlockBlobReference( Path.GetFileName(sourceFilePath) );
        HashSet<string> blocklist = new HashSet<string>();

        byte[] fileContent = File.ReadAllBytes(sourceFilePath);
        const int pageSizeInBytes = 10485760;
        long prevLastByte = 0;
        long bytesRemain = fileContent.Length;

        do
        {
            long bytesToCopy = Math.Min(bytesRemain, pageSizeInBytes);
            byte[] bytesToSend = new byte[bytesToCopy];
            Array.Copy(fileContent, prevLastByte, bytesToSend, 0, bytesToCopy);
            prevLastByte += bytesToCopy;
            bytesRemain -= bytesToCopy;

            //create blockId
            string blockId = Guid.NewGuid().ToString();
            string base64BlockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(blockId));

            blob.PutBlock(
                base64BlockId,
                new MemoryStream(bytesToSend, true),
                null
                );

            blocklist.Add(base64BlockId);

        } while (bytesRemain > 0);

        //post blocklist
        blob.PutBlockList(blocklist);

        return "Success";
    }
    catch (Exception ex)
    {
        return ex.Message;
    }
}

Он хорошо работает для загрузки большого файла (кто-то дает решение от здесь ).

Пожалуйста, дайте мне знать, если вы можете работать с ним.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...