使用PowerShell(通过Get-AzureStorageBlobContent),Azure blob下载速度极慢,但是通过Azure Explorer等快速下载?

时间:2013-08-12 19:26:17

标签: powershell azure azure-storage azure-storage-blobs

使用非常基本的代码循环访问我的存储帐户并将所有容器和blob镜像到我的本地磁盘,我发现 Get-AsureStorageBlobContent cmdlet非常慢?无论blob大小如何,它似乎需要每个blob实时第二或第二个......当我们有数千个小文件时,这会增加相当大的开销。

相比之下,在同一台机器和网络连接(甚至同时运行)上,Azure Explorer可以将速度相同的批量复制速度提高10倍到20倍,而AzCopy的速度提高了100倍(异步),所以显然它不是网络问题。

是否有更有效的方式来使用Azure存储cmdlet,或者它们只是天性慢的狗? Get-AzureStorageContainer 的帮助提到了一个 -ConcurrentTaskCount 选项,它暗示了一些异步的能力,但是没有关于如何实现异步的文档,并且它只能在单项我不知道它怎么可能?

这是我正在运行的代码:

$localContent       = "C:\local_copy"
$storageAccountName = "myblobaccount"
$storageAccountKey  = "mykey"

Import-Module Azure    

$blob_account = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -Protocol https

Get-AzureStorageContainer -Context $blob_account | ForEach-Object {
    $container = $_.Name

    Get-AzureStorageBlob -Container $container -Context $blob_account | ForEach-Object {
        $local_path = "$localContent\{0}\{1}" -f$container,$_.Name

        $local_dir = Split-Path $local_path
        if (!(Test-Path $local_dir)) {
            New-Item -Path $local_dir -ItemType directory -Force
        }
        Get-AzureStorageBlobContent -Context $blob_account -Container $container -Blob $_.Name -Destination $local_path -Force | Out-Null
    }
}

2 个答案:

答案 0 :(得分:2)

我查看了Github上Get-AzureStorageBlobContent的源代码,发现了一些有趣的东西,可能会导致下载blob的速度变慢(特别是小尺寸的blob):

第165行:

ICloudBlob blob = Channel.GetBlobReferenceFromServer(container, blobName, accessCondition, requestOptions, OperationContext);

这段代码的作用是它向服务器发出请求获取blob类型的请求。因此,您需要为服务器为每个blob添加一个额外的请求。

第252行 - 262行:

        try
        {
            DownloadBlob(blob, filePath);

            Channel.FetchBlobAttributes(blob, accessCondition, requestOptions, OperationContext);
        }
        catch (Exception e)
        {
            WriteDebugLog(String.Format(Resources.DownloadBlobFailed, blob.Name, blob.Container.Name, filePath, e.Message));
            throw;
        }

如果查看上面的代码,它首先会下载blob DownloadBlob并尝试获取blob属性Channel.FetchBlobAttributes。我没有查看Channel.FetchBlobAttributes函数的源代码,但我怀疑它还向服务器发出了一个请求。

因此,为了下载单个blob,本质上代码向服务器发出3个请求,这可能是缓慢的原因。确切地说,您可以通过Fiddler跟踪您的请求/响应,并查看cmdlet与存储的完全交互。

答案 1 :(得分:0)

结帐Blob Transfer Utility。它使用Azure api,这也是Azure Explorer正在使用的一个很好的选择。 BTU是开源的,因此测试cmdlet是否是问题要容易得多。