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 的快照异地备份功能早日支持。