使用非常基本的代码循环访问我的存储帐户并将所有容器和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
}
}
答案 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是否是问题要容易得多。