4

我需要将一个存储帐户复制到另一个。我创建了一个Runbook并安排它每天运行。这是一个增量副本。

我正在做的是

  1. 列出源存储容器中的 blob
  2. 检查目标存储容器中的 blob
  3. 如果目标容器中不存在,则复制 blobStart-AzureStorageBlobCopy

虽然这适用于小尺寸的容器,但这需要很长时间,并且对于具有 1000 万块 blob 的容器来说肯定是不划算的,因为每次运行任务时,我都必须遍历所有这 1000 万个 blob。

我在文档中没有看到它,但是有什么方法可以DateModifedSinceGet-AzureStorageBlob -DateModifiedSince date在 powershell 中那样使用条件标头。

我没有尝试过,但我可以看到可以DateModifiedSincenodejs 库中使用

无论如何我可以用powershell来做到这一点,这样我就可以使用了Runbooks吗?

编辑:

使用 AzCopy 制作了包含 700 万个 Blob 的存储帐户副本,我上传了几个新 Blob 并再次启动了 azcopy。复制几个新上传的文件仍然需要大量时间。

AzCopy /Source:$sourceUri /Dest:$destUri /SourceKey:$sourceStorageKey /DestKey:$destStorageAccountKey /S /XO /XN /Y

可以立即过滤具有 blob 名称的 blob

例如Get-AzureStorageBlob -Blob将立即从 700 万条记录中返回 blob

也应该可以过滤具有其他属性的 blob..

4

2 回答 2

4

我不确定这是否是实际的正确答案,但我现在已经采用了这个解决方案。

AzCopy 更快一些,但由于它是可执行的,我无法在自动化中使用它。

我编写了自己的运行手册(可以修改为工作流),它实现了以下 AzCopy 命令

AzCopy /Source:$sourceUri /Dest:$destUri /SourceKey:$sourceStorageKey /DestKey:$destStorageAccountKey /S /XO /Y

  1. 查看列表 blob,我们只能通过 blob 前缀来拟合 blob。所以我不能拉出按修改日期过滤的 blob。这让我不得不拉出整个 blob 列表。
  2. 我每次使用 ContinuationToken 从源和目标 Get-AzureStorageBlob 提取 20,000 个 blob
  3. 循环提取 20,000 个源 blob,查看它们是否在目标中不存在或在源中已被修改
  4. 如果 2 为真,那么我将这些 blob 写入目标
  5. 通过 700 万个 blob 大约需要 3-4 小时。任务将根据要写入目标的 blob 数量而延长。

一段代码

    #loop throught the source container blobs, 
    # and copy the blob to destination that are not already there
    $MaxReturn = 20000
    $Total = 0
    $Token = $null
    $FilesTransferred = 0;
    $FilesTransferSuccess = 0;
    $FilesTransferFail = 0;
    $sw = [Diagnostics.Stopwatch]::StartNew();
    DO
    {
        $SrcBlobs = Get-AzureStorageBlob -Context $sourceContext -Container $container -MaxCount $MaxReturn  -ContinuationToken $Token | 
            Select-Object -Property Name, LastModified, ContinuationToken

        $DestBlobsHash = @{}
        Get-AzureStorageBlob -Context $destContext -Container $container -MaxCount $MaxReturn  -ContinuationToken $Token  | 
            Select-Object -Property Name, LastModified, ContinuationToken  | 
                ForEach { $DestBlobsHash[$_.Name] = $_.LastModified.UtcDateTime }


        $Total += $SrcBlobs.Count

        if($SrcBlobs.Length -le 0) { 
            Break;
        }
        $Token = $SrcBlobs[$SrcBlobs.Count -1].ContinuationToken;

        ForEach ($SrcBlob in $SrcBlobs){
            # search  in destination blobs for the source blob and unmodified, if found copy it
            $CopyThisBlob = $false

            if(!$DestBlobsHash.count -ne 0){
                $CopyThisBlob = $true
            } elseif(!$DestBlobsHash.ContainsKey($SrcBlob.Name)){
                $CopyThisBlob = $true
            } elseif($SrcBlob.LastModified.UtcDateTime -gt $DestBlobsHash.Item($SrcBlob.Name)){
                $CopyThisBlob = $true
            }

            if($CopyThisBlob){
                #Start copying the blobs to container
                $blobToCopy = $SrcBlob.Name
                "Copying blob: $blobToCopy to destination"
                $FilesTransferred++
                try {
                    $c = Start-AzureStorageBlobCopy -SrcContainer $container -SrcBlob $blobToCopy  -DestContainer $container -DestBlob $blobToCopy -SrcContext $sourceContext -DestContext $destContext -Force
                    $FilesTransferSuccess++
                } catch {
                    Write-Error "$blobToCopy transfer failed"
                    $FilesTransferFail++
                }   
            }           
        }
    }
    While ($Token -ne $Null)
    $sw.Stop()
    "Total blobs in container $container : $Total"
    "Total files transferred: $FilesTransferred"
    "Transfer successfully: $FilesTransferSuccess"
    "Transfer failed: $FilesTransferFail"
    "Elapsed time: $($sw.Elapsed) `n"
于 2016-04-25T09:21:06.707 回答
0

最后修改的存储在 iCloudBlob 对象中,你可以用 Powershell 访问它,像这样

$blob = Get-AzureStorageBlob -Context $Context  -Container $container
$blob[1].ICloudBlob.Properties.LastModified

哪个会给你

日期时间 : 31/03/2016 17:03:07
UtcDateTime : 31/03/2016 17:03:07
LocalDateTime : 31/03/2016 18:03:07
日期 : 31/03/2016 00:00:00
日期 : 31
DayOfWeek : 星期四
DayOfYear : 91
小时 : 17
毫秒 : 0
分钟 : 3
月 : 3
偏移量 : 00:00:00
秒 : 7滴答声 :
635950405870000000
UtcTicks : 635950405870000000
TimeOfDay : 17:03:07

通读API我认为不可能使用名称以外的任何参数对容器执行搜索。我只能想象 nodejs 库仍然检索所有 blob,然后过滤它们。

不过我会再深入一点

于 2016-04-08T12:17:39.550 回答