上海-北京間通過Azure Storage的RA-GRS型別的儲存賬戶進行快速複製

衡子發表於2016-04-12

Azure的Blob儲存分成多種型別,目前主要有:

其中RA-GRS可以在上海-北京兩個資料中心間同步資料。並且,在第二個資料中心可以只讀的方式讀取這個儲存賬戶中的Blob內容。

雖然GRS採用的是準實時同步,不是實時同步,但對很多需要快速恢復虛擬機器、檔案的情況已經足夠使用。

本文將介紹,如何採用RA-GRS在第二個資料中心可以讀的特性,在第二個資料中心快速的複製磁碟檔案的功能。

下面的Powershell指令碼將使用者輸入的VM資訊獲取OSDisk和DataDisk的資訊,把這些Disk複製到使用者指定的型別是RA-GRS的儲存賬戶中,並將這些Disk在第二個資料中心複製到使用者指定的目標儲存賬戶中。具體步驟如下:

第一步,把VM的Disk複製到相同儲存賬戶的臨時Container:temp中。這一步的作用是將正在讀寫的Disk變成一個普通的VHD檔案。

第二步,把LRS的temp中的VHD檔案複製到RA-GRS的儲存賬戶的temp中。這一步比較耗時,主要看Disk的實際使用量。

第三步,等待數分鐘,Azure平臺會自動將VHD檔案複製到另外一個資料中心的Secondary儲存賬戶中。

第四步,把VHD檔案複製到另外一個資料中心的目標儲存賬戶中,並生成Disk。後續可以使用這些Disk建立VM。

具體的PowerShell指令碼如下:

 

function Copy-GRSVM {
 
param(

#The GRS_RA type storage account
[Parameter(Mandatory=$true)]
[String]$GRS_StorageAccountName,

#The Dest Storage account, in another region
[Parameter(Mandatory=$true)]
[String]$Dst_StorageAccountName,

#VM cloud service name
[Parameter(Mandatory=$true)]
[String]$VM_Service,

#VM Name
[Parameter(Mandatory=$true)]
[String]$VM_Name
)
 


#Get the VM, using the service name and vm name
$vm = get-azurevm -ServiceName $VM_Service -Name $VM_Name

#Get the VM OS type
$ostype = $vm.VM.OSVirtualHardDisk.OS

#Copy OS Disk
$oslink = $vm.vm.OSVirtualHardDisk.MediaLink.OriginalString

Copy-diskfromlink -GRS_StorageAccountName $GRS_StorageAccountName -Dst_StorageAccountName $Dst_StorageAccountName -link $oslink -isOSDisk $true -OSType $ostype

#copy Data Disk
$datadisks = $vm.vm.DataVirtualHardDisks
foreach ($datadisk in $datadisks)
{
  $datadisklink = $datadisk.MediaLink.OriginalString
  Copy-diskfromlink -GRS_StorageAccountName $GRS_StorageAccountName -Dst_StorageAccountName $Dst_StorageAccountName -link $datadisklink -isOSDisk $false -OSType $ostype
}

}

function Copy-diskfromlink {

param(

#The GRS_RA type storage account
[Parameter(Mandatory=$true)]
[String]$GRS_StorageAccountName,

#The Dest Storage account, in another region
[Parameter(Mandatory=$true)]
[String]$Dst_StorageAccountName,

#VM disk link
[Parameter(Mandatory=$true)]
[String]$link,

#VM OS type
[Parameter(Mandatory=$true)]
[String]$OSType,

#The disk is OS
[Parameter(Mandatory=$true)]
[boolean]$isOSDisk
)

$diskname = $link.Split("/")[-1]
$vmdiskctn = $link.Split("/")[-2]

#Get the VM storage account's name, keys and context.
$VM_StorageAccountName = $link.Split("/")[-3].Split(".")[0]
$vmsa = Get-AzureStorageAccount -StorageAccountName $VM_StorageAccountName
$vmsakey = Get-AzureStorageKey -StorageAccountName $vmsa.Label
$vmsactx = New-AzureStorageContext -StorageAccountName $vmsa.Label -StorageAccountKey $vmsakey.Primary

#Get the GRS_RA storage account's name, keys and context
$grsa = Get-AzureStorageAccount -StorageAccountName $GRS_StorageAccountName
$grsakey = Get-AzureStorageKey -StorageAccountName $grsa.Label 
$grsactx = New-AzureStorageContext -StorageAccountName $grsa.Label -StorageAccountKey $grsakey.Primary
$grsactn = Get-AzureStorageContainer -Context $grsactx | Where-Object {$_.name -match "temp"}

#Define the connection string, which is the GRS_RA storage account secondary region endpoint
$Connect_str="DefaultEndpointsProtocol=https;AccountName=" + $grsa.StorageAccountName + ";AccountKey=" + $grsakey.Primary + ";BlobEndpoint=http://" + $grsa.StorageAccountName + "-secondary.blob.core.chinacloudapi.cn;"
$grdstCtx = New-AzureStorageContext -ConnectionString $Connect_str

#Get the dest storage account's name, keys and context
$dstsa = Get-AzureStorageAccount -StorageAccountName $Dst_StorageAccountName
$dstsakey = Get-AzureStorageKey -StorageAccountName $dstsa.StorageAccountName 
$dstsactx = New-AzureStorageContext -StorageAccountName $dstsa.StorageAccountName -StorageAccountKey $dstsakey.Primary



#In VM Storage account, if the temp container is not presented, create it.
$vmsactn = Get-AzureStorageContainer -Context $vmsactx | Where-Object {$_.name -match "temp"}
if ($vmsactn)
  {write-host "temp container is already created!"}
else
  {New-AzureStorageContainer -Name temp -Context $vmsactx}

#If the GRS_RA storage account type is not GRS_RA, change it to that.
if ($grsa.AccountType -eq "Standard_RAGRS")
  {write-host "the storage account is GRS_RA"}
else
  {Set-AzureStorageAccount -StorageAccountName $grsa.Label -Type Standard_RAGRS}

#In GRS_RA storage account, if the temp container is not presented, create it.
 if ($grsactn)
   {write-host "temp container is already created!"}
 else
   {New-AzureStorageContainer -Name temp -Context $grsactx}

#Copy VM OS disk to the same Storage account's temp conainter. This copy will be very fast. And is the only way to copy a starting VM's disk to a block blob file.
Start-AzureStorageBlobCopy -SrcBlob $diskname -SrcContainer $vmdiskctn -Context $vmsactx -DestContainer temp -DestBlob $diskname -DestContext $vmsactx -Force

#Monitor the copy status, wait until the copy success.
$i=0
while($true)
{
   $i=$i+1
   write-host "Copying vhd from VM Storage Account vhd container to temp container, elapsing"$i"0 seconds"
   $cpstatus = Get-AzureStorageBlobCopyState -Container temp -Context $vmsactx -Blob $diskname
   $percent=$cpstatus.BytesCopied/$cpstatus.TotalBytes * 100
   write-host "Already copying" $percent "%"
   if($cpstatus.Status -eq "Pending")
   {Start-Sleep -s 10}
   else
   {
     Write-Host "copy ok"
     break}
}

#Copy the disk vhd file, from the VM storage temp container to the GRS_RA storage account temp container. This copy will spend lots of time.
Start-AzureStorageBlobCopy -SrcBlob $diskname -SrcContainer temp -Context $vmsactx -DestContainer temp -DestBlob $diskname -DestContext $grsactx -Force

#Monitor the copy status, wait until the copy success.
$i=0
while($true)
{
   $i=$i+1
   write-host "Copying vhd from VM Storage Account temp container to GRS Storage account temp container, elapsing"$i"0 seconds"
   $cpstatus = Get-AzureStorageBlobCopyState -Container temp -Context $grsactx -Blob $diskname
   $percent=$cpstatus.BytesCopied/$cpstatus.TotalBytes * 100
   write-host "Already copying" $percent "%"
   if($cpstatus.Status -eq "Pending")
   {Start-Sleep -s 10}
   else
   {
     Write-Host "copy ok"
     break}
}



#Because the GRS_RA is best effort way to sync the data between two regions, wait 5 minutes to ensure the data is sync.
write-host "wait 5 minutes"
Start-Sleep -Seconds 300

#Check the disk is presented in the secondary region's GRS_RA storage account's temp folder.
while($true)
{
   write-host "Check whether the disk is in the GRS storage account seconday site"
   $grdstblob = Get-AzureStorageBlob -Container temp -Blob $diskname -Context $grdstCtx

   if($grdstblob)
   { write-host "disk ok"
     break}
   else
   {
     Start-Sleep -s 10
     }
}



#Copy the disk vhd file from the GRS_RA seconday region temp container to the dest storage account's vhds container
Start-AzureStorageBlobCopy -SrcContainer temp -SrcBlob $diskname -Context $grdstCtx -DestContainer vhds -DestContext $dstsactx -DestBlob $diskname

#Monitor the copy status, wait until the copy success.
$i=0
while($true)
{
   $i=$i+1
   write-host "Copying vhd from GRS Account secondary site temp container to destination Storage Account temp container, elapsing"$i"0 seconds"
   $cpstatus = Get-AzureStorageBlobCopyState -Container vhds -Context $dstsactx -Blob $diskname
   $percent=$cpstatus.BytesCopied/$cpstatus.TotalBytes * 100
   write-host "Already copying" $percent "%"
   if($cpstatus.Status -eq "Pending")
   {Start-Sleep -s 10}
   else
   {
     Write-Host "copy ok"
     break}
}

#remove the temp vhd file in 2 temp containers
write-host "Removing the Temp vhd file"
Remove-AzureStorageBlob -Context $vmsactx -Container temp -Blob $diskname
Remove-AzureStorageBlob -Context $grsactx -Container temp -Blob $diskname

#Create the new disk from the vhd file
write-host "create disk from vhd file"
$dst_disk_link = "https://" + $Dst_StorageAccountName + ".blob.core.chinacloudapi.cn/vhds/" +$diskname
if($isOSDisk)
{
  Add-AzureDisk -DiskName $diskname -MediaLocation $dst_disk_link -OS $OSType
}
else
{
  Add-AzureDisk -DiskName $diskname -MediaLocation $dst_disk_link
}
 
}

Copy-GRSVM -GRS_StorageAccountName hweast -Dst_StorageAccountName hwnorth -VM_Service hwcentos65 -VM_Name hwcentos65-03

 

 

 

相關文章