Azure Managed Disk 增量快照

        今天小文一篇介绍 Azure Managed Disk 的增量快照功能。在增量快照功能之前,对于托管磁盘,用户只能通过全量的方式对磁盘进行快照,快照成本不优;其次对于快照做异地备份恢复场景,全量快照同样会增加备份的时间并带来额外流量费用。通过 Azure Managed Disk 对于增量快照的支持,用户可以对托管磁盘进行一盘多照,每次快照只会产生前一次快照所产生的差异数据,并且 Azure 会帮用户托管相同托管磁盘的快照之间的依赖关系。

 

         目前该功能在国内 Azure 和海外 Azure 都已经 GA,目前在国内还不支持 Portal 配置,本文为大家介绍通过命令行如何进行增量快照。

环境说明:

-- 资源组名称 resourcegroup
sanpshotdemo

-- 托管磁盘资源 resourceid
/subscriptions/<subscriptionid>/resourceGroups/<resourcegroup>/providers/Microsoft.Compute/disks/<manageddiskname>

-- 快照1名称
demovm_OsDisk_snapshot1

-- 快照2名称
demovm_OsDisk_snapshot2

演示环境中通过 Azure CLI 创建对一台 Windows 10 演示 VM 的系统盘分别创建两次增量快照 demovm_OsDisk_snapshot1 和 demovm_OsDisk_snapshot2 ,两次快照之间在演示 VM 之上下载文件,仿真磁盘数据发生变化。

创建 demovm_OsDisk_snapshot1,相较之前的全量备份,命令行上增加了 --incremental 参数

# 按照实际部署替换 <subscription>, <resourcegroup>, <manageddiskname>
az snapshot create -g <resourcegroup> -n demovm_OsDisk_snapshot1 -l <location> --source "/subscriptions/<subscription>/resourceGroups/<resosurcegroup>/providers/Microsoft.Compute/disks/<mangeddiskname>" --incremental

创建 demovm_OsDisk_snapshot2

# 按照实际部署替换 <subscription>, <resourcegroup>, <manageddiskname>
az snapshot create -g <resourcegroup> -n demovm_OsDisk_snapshot1 -l <location> --source "/subscriptions/<subscription>/resourceGroups/<resosurcegroup>/providers/Microsoft.Compute/disks/<mangeddiskname>" --incremental

通过快照创建托管磁盘并创建主机的方式和全量快照没有变化,这里不做赘述,大家可以在 Portal 上选择磁盘,通过快照创建磁盘,再由创建的磁盘创建主机即可。

下面我们来介绍另外一个场景,结合增量备份来做异地备份的场景。无论全量快照和增量快照,默认快照生成的区域与原始对象(托管磁盘)所在的区域是相同的,在极端情况下如果 Region 不可用了,该快照也不可用,业务无法恢复。通过增量快照的方式,可以大大减少异地快照备份传输的数据,只需要每次对增量数据进行传输即可。

 

上述架构图中,在托管磁盘源 Region,用户客户通过计划任务持续对托管磁盘进行增量快照,在异地备份 Region,通过托管磁盘的第一个增量快照来创建一个 Base Page Blob, 该 Base Page Blob 作为地基,后续源 region 的增量快照产生的增量数据,通过 Page 数据拷贝的方式,将增量数据覆盖写入到 Base Page Blob,如果异地备份 region 考虑快照备份的多版本,可以在每次增量快照数据覆写 Base Page Blob 前,对 Base Page Blob 做快照。上述逻辑目前在托管磁盘的快照服务中还不是 Build-In 的内置功能,客户目前可以通过 SDK 来开发实现,本文以 Python SDK 示例代码为大家介绍上述实现:

上面演示中已经存在了两个增量 Snapshot,snapshot1 和 snapshot2,下面的示例代码分两部分,第一部分 Base Page Blob 创建拷贝,第二部分增量的快照数据拷贝,目前相关引用函数在 12.2.0 版本 SDK 中支持。

Base Page Blob 创建拷贝:

from azure.storage.blob import BlobClient, BlobServiceClient
# initiate snapshot sas url
snapshot1_sas_url = "<snapshot1_sas>"
snapshot2_sas_url = "<snapshot2_sas>"
# initiate target storage account parameter
target_account_url = "<storage_account_url>"
target_access_key = "<storage_access_key>"
target_container = "page"
target_base_blob = "snapshot.vhd"
target_incremental_blob = "snapshot.vhd"
# initiate source blob
source_blob_client = BlobClient.from_blob_url(snapshot1_sas_url)
source_size = source_blob_client.get_blob_properties().size
source_pageRanges = source_blob_client.get_page_ranges()
# initiate destination blob
target_blob_service_client = BlobServiceClient(target_account_url, target_access_key)
target_blob_client = target_blob_service_client.get_blob_client(target_container, target_base_blob)
target_blob_client.create_page_blob(source_size)

# Using PutPage API to do the base page blob data copy FourMegabyteAsBytes
= 4 * 1024 * 1024 for range in source_pageRanges[0]: print(range) range_size = range.get('end') + 1 - range.get('start') suboffset = 0 while suboffset < range_size: subrangesize = min(range_size - suboffset, FourMegabyteAsBytes) target_blob_client.upload_pages_from_url(source_snapshot1_url, range.get('start') + suboffset, subrangesize, range.get('start') + suboffset) suboffset = suboffset + FourMegabyteAsBytes

增量快照数据拷贝:

# Using get_page_range_diff_managed_disk api to get the incremental page data
blob_client = BlobClient.from_blob_url(snapshot2_sas_url)
diff_page_range = blob_client.get_page_range_diff_for_managed_disk(snapshot1_sas_url)

# Using upload_pages_from_url and clear_page to do the incremental page data copy
FourMegabyteAsBytes = 4 * 1024 * 1024
# OverWrite the Existing Page Block
for range in diff_page_range[0]:
    print(range)
    range_size = range.get('end') + 1 - range.get('start')
    suboffset = 0
    while suboffset < range_size:
        subrangesize = min(range_size - suboffset, FourMegabyteAsBytes)
        target_blob_client.upload_pages_from_url(snapshot2_sas_url, range.get('start') + suboffset, subrangesize, range.get('start') + suboffset)
        suboffset = suboffset + FourMegabyteAsBytes
# Delete the dropped Page Block
for range in diff_page_range[1]:
    print(range)
target_blob_client.clear_page(range.get('start'), range.get('end') + 1 - range.get('start'))

        今天的内容介绍到这里,希望对大家有所帮助,后续也希望 Azure Managed Disk Build-In 的快照异地备份功能早日支持。

posted @ 2020-03-31 09:42  wekang  阅读(...)  评论(...编辑  收藏