VMware 虚拟化编程(10) — VMware 数据块修改跟踪技术 CBT

标签: vmware 函数 虚拟化 编程 数据
1278人阅读 评论(0) 收藏 举报
分类:

目录

前文列表

VMware 虚拟化编程(1) — VMDK/VDDK/VixDiskLib/VADP 概念简析
VMware 虚拟化编程(2) — 虚拟磁盘文件类型详解
VMware 虚拟化编程(3) —VMware vSphere Web Service API 解析
VMware 虚拟化编程(4) — VDDK 安装
VMware 虚拟化编程(5) — VixDiskLib 虚拟磁盘库详解之一
VMware 虚拟化编程(6) — VixDiskLib 虚拟磁盘库详解之二
VMware 虚拟化编程(7) — VixDiskLib 虚拟磁盘库详解之三
VMware 虚拟化编程(8) — 多线程中的 VixDiskLib
VMware 虚拟化编程(9) — VMware 虚拟机的快照

数据块修改跟踪技术 CBT

CBT(Changed Block Tracking) 数据块修改跟踪技术,是 VMware 实现「增量备份」的底层支撑技术。CBT 的优势在于节约空间,它允许只备份发生了修改的数据。在 CBT 被引入之前,每次都必须要备份整个虚拟机,而不是增量备份。所谓增量备份,即仅备份两个快照时间点之间所被修改过的数据。开启了 CBT 的虚拟机会在其数据储存目录下新建一个 -ctk.vmdk 文件,用于记录数据块修改的跟踪信息。但开启 CBT 会对虚拟机的虚拟磁盘带来一些性能损失,所以默认会关闭 CBT。

CBT 的工作原理就是让 VMKernel 监控自上次快照时间点以来有那些数据块中的数据被改变了,并记录下这些被改变的数据块的偏移量,依靠这些偏移量就能够获取数据块中的修改数据了。

以下场景都支持 CBT:

  • 存储在 VMFS 上的虚拟磁盘(SAN or Local)
  • NFS 上的虚拟磁盘
  • 虚拟兼容模式的 RDM(裸设备映射)

以下场景不支持 CBT

  • 物理兼容模式的 RDM

为虚拟机开启 CBT

默认情况下 CBT 功能是禁用的,因为它会引起一个很小但是可被测量到的性能损耗。开启 CBT 的前提条件需要虚拟机版本为 7 或更高,我们可以使用 PropertyCollector 从 VirutalMachine ManagedObject 中获取这个 CBT 的属性域,如果其中含有 changeTrackingSupported 属性值,就该虚拟机支持 CBT 功能。

  • 使用程序设置 CBT
VirtualMachineConfigSpec configSpec = new VirtualMachineConfigSpec();
configSpec.changeTrackingEnabled = new Boolean(true);
ManagedObjectReference taskMoRef = serviceConnection.getService().ReconfigVm_Task(targetVM_MoRef, configSpec);
  • 手动设置 CBT
    • 右击虚拟机,选择「Edit Settings」
    • 点击「Options」
    • 点击「Advanced section」下的「General」,点击「Configuration Parameters」,开启「Configuration Parameters」窗口后,查找或添加「ctkEnabled」项,设置为「true」,并设置每个磁盘的「ctkEnabled=true」

在设置了 CBT 之后,需要重启虚拟机生效。

NOTE: vSphere WS API 能调用 configSpec.changeTrackingEnabled = new Boolean(true) 来动态的设置 CBT 状态,而不需关闭虚拟机。

CBT 修改数据块偏移量获取函数 QueryChangedDiskAreas

VMware vSphere WS API 中提供的 QueryChangedDiskAreas Method 能够帮助开发者获得虚拟机 CBT 的功能,该函数需要提供以下参数:

  • _this:目标 VirtualMachine moRef
  • snapshot:虚拟机当前的 Snapshot moRef
  • deviceKey:目标虚拟磁盘的 Id
  • startOffset:指定开始检查 CBT 的 offset,一般可以为 0
  • changeId:虚拟磁盘在某个时间点上的状态标识符,是一个格式为 <UUID>/<nnn> 的数字序列字符串,如果 <UUID> 改变了,跟踪信息就会失效。每次创建虚拟机快照时都会生成一个新的 changeId,你可以从快照的虚拟磁盘对象或 snapshot_moref 中获取新的 changeId。

QueryChangedDiskAreas 返回的是 DiskChangeInfo 数据对象,它包含一组 DiskChangeInfo.DiskChangeExtent 元素,分别表示已修改数据块磁盘区域的开始位移和长度,DiskChangeInfo 覆盖了整个磁盘区域的开始位移和长度。
EXAMPLE:(offset,length) 表示一个发生了修改的数据块的偏移量

(117768192, 65536)
(132120576, 65536)
(145096704, 43122688)
(265289728, 65536)
(958398464, 65536)

使用 QueryChangedDiskAreas 得到已修改数据块偏移量信息的前提条件是需要在创建快照前启用 CBT 功能,如果在启用 CBT 前调用该 Method 就会触发 FileFault 错误。

changeId

changeId 实际上就是虚拟磁盘在某个时间点的标识符。当我们调用 QueryChangedDiskAreas Method 时,除了可能会为形参 changeId 传入一串数字序列字符串之外,还可能会传入一个「*」号。

在使用 changeId 时,应该注意以下几点

  • 当虚拟机还没有快照时,虚拟磁盘的 changeId 初始值应该为 none 表示未设置的。

  • 当虚拟机创建第一个快照时,应该将传入「*」号,表示虚拟磁盘上所有的实际已分配的区域,同时忽略稀疏类型磁盘的未分配区域。需要注意的是,只有当虚拟磁盘的 changeId 初始值为 none 时,changeId=* 才会生效。换句话说,只有当虚拟机仅拥有一个快照时调用 QueryChangedDiskAreas,才能够将 changeId 设置为「*」,并且能够以此获得虚拟机的全量数据偏移量。

  • 在此之后的每次创建快照都会生成一个新的 changeId。如果 changeId 不再为 none,则表示虚拟机已经进行过至少一次快照,此后调用 QueryChangedDiskAreas 就能够得到自 changeId 标识的快照时间点以来所发生了修改的数据块偏移量,也就是增量数据偏移量。

这里写图片描述

总结一下,使用「*」时,存在下面两点限制

  • 虚拟磁盘必须存放在 VMFS 上。
  • 启动 CBT 时,虚拟机必须没有快照存在。

获取虚拟磁盘当前的 changeId
我们能够用过 VirutalMachine ManagedObject 的 vim.vm.device.VirtualDevice.VirtualDisk 配置项中找到虚拟机每一块虚拟磁盘的 backing 信息。如果 backing 的类型是下列中的一个,你就可以使用 BackingInfo 数据对象的 changeId 属性来获得其 changeId:

  • vim.vm.device.VirtualDevice.VirtualDiskFlatVer2BackingInfo
  • vim.vm.device.VirtualDevice.VirtualDiskSparseVer2BackingInfo
  • vim.vm.device.VirtualDevice.VirtualDiskRawDiskMappingVer1BackingInfo
  • vim.vm.device.VirtualDevice.VirtualDiskRawDiskVer2BackingInfo

最后总结一下,QueryChangedDiskAreas(..., "*") 实际上会返回虚拟磁盘被实际使用的(Thin)或者整个被分配的(Thick)的数据空间偏移量。CBT 的实现依赖于「虚拟磁盘的未分配区域」以及「 VMFS 的数据块延迟清零」两者的定义和特性。因此,CBT 只有在 VMFS 数据存储上才会返回有意义的结果。在其他存储类型上,要么就失败,要么就返回包含整个磁盘的单个内容。

在开启的 CBT 的前提下,第一次调用 QueryChangedDiskAreas(..., "*") 时,它会返回虚拟磁盘上所有 已经使用的 数据块区域,后续的调用则会返回 已修改的 数据块区域,而不是 已分配的 区域。

在没有开启 CBT 的前提下,在快照后调用 QueryChangedDiskAreas,则会返回 已分配的 区域,对于精简置备虚拟磁盘和延迟清零的厚置备磁盘而言,那些 已分配但未使用的 区域则会使用零值填充。也就是说这种情况下,即便是精简置备虚拟磁盘,其全量备份所得到的数据量等于为其所分配的数据量,而非实际所使用了的数据量。

一个 QueryChangedDiskAreas 的 DEMO

String changeId; //Already initialized: changeId, snapshotMoRef, the VM
ManagedObjectReferencesnapshotMoRef;
ManagedObjectReferencetheVM;
int diskDeviceKey; //Identifies the virtual disk.
VirutalMachine.DiskChangeInfochanges;
long startPostion = 0;
do {
       changes =theVM.QueryChangedDiskAreas(snapshotMoRef, diskDeviceKey, startPostion,changeId);
       for (int i = 0; i < changes.changedAread.length;i++) {
              long length =changes.changedArea[i].length;
              long offset =changes.chagedArea[i].startOffset;
              //
              // Go get and save disk data here
       }
       startPosition = changes.startOffset +changes.length;
} while (startPosition< diskCapacity);

在这个 DEMO 里,QueryChangedDiskAreas 被反复调用,同时开始检查位置 startPosition 在虚拟磁盘中不断往后移动。这是因为对于大型虚拟磁盘而言,ChangedDiskArea 数组很可能会占用大量的内存。

NOTE:需要注意的是,QueryChangedDiskAreas 获得的是已修改数据块的偏移量,而非实际的已修改数据。

应用 QueryChangedDiskAreas 设计的增量/差异备份算法

假设在 T1 时间点创建了一个初始的全量备份,之后在 T2、T3 时间点分别创建了增量备份。当然,你也可以使用差异备份,只是它会消耗更多的备份时间和带宽,但是拥有更少的还原时间。

  • T1 时间的全量备份

    1. 记录虚拟机的配置信息 VirtualMachineConfigInfo。
    2. 创建虚拟机快照,命名为 snapshot_T1。
    3. 获得并保存快照中各个虚拟磁盘的 changeId,changeId_T1。
    4. 备份调用 queryChangedDiskAreas(…, “*”) 所返回的已修改数据块扇区对应的数据。
    5. 删除快照 snapshot_T1。
  • T2 时间的增量备份

    1. 创建虚拟机快照,命名为 snapshot_T2。
    2. 获得并保存快照中各个虚拟磁盘的 changeId,changeId_T2。
    3. 备份调用 queryChangedDiskAreas(snapshot_T2, …, changedId_T1)返回的已修改数据块扇区对应的数据。
    4. 删除快照snapshot_T2。
  • T3 时间的增量备份

    1. 创建虚拟机快照,命名为 snapshot_T3 (此时你无法再获得 T1 到 T2 两个时间点之间的以修改数据块列表)
    2. 获得并保存快照中各个虚拟磁盘的 changeId,changeId_T3。
    3. 备份调用 queryChangedDiskAreas(snapshot_T3, …, changedId_T2)返回的已修改数据块扇区对应的数据。如果你希望执行差异备份,则调用 queryChangedDiskAreas(snapshot_T3, …, changedId_T1)。
      4删除快照snapshot_T3。
  • T4 时间的灾难恢复

    1. 使用之前保存的 VirtualMachineConfigInfo 中的配置参数,创建一个没有 GuestOS,没有虚拟磁盘的新虚拟机。
    2. 从 T3 的增量备份中还原数据,并记录还原了哪些扇区。
    3. 从 T2 中还原增量备份的数据,跳过 2 中已记录(已还原)的扇区,并记录还原了哪些扇区。如果 T3 是差异备份,则跳过此步骤。
    4. 从 T1 完全备份中还原数据,并跳过 2、3 中已记录(已还原)的扇区。
    5. 打开恢复过后的虚拟机。

NOTE:从后往前还原的目的就是获取同一数据块上最新的数据,从而避免不需要的数据拷贝。

查看评论

VMWare WorkStation 10 管理

-
  • 1970年01月01日 08:00

Vmware12安装Redhat6.8

Vmware12安装Redhat6.8
  • ise_yingzi
  • ise_yingzi
  • 2017-07-01 21:42:52
  • 235

VMware下提示USB连接失败,驱动程序错误

如果没有开启VMUSBArbService服务。1.在服务里找到VMUSBArbService,开启。2.卸载AMD南桥驱动中的USB过滤器驱动。再去开启VMUSBArbService服务。3.USB...
  • banzhuan133
  • banzhuan133
  • 2018-03-03 15:48:22
  • 442

Vmware Vcenter6.5 全新安装及群集配置介绍

【摘要】 VMwarevCenterServer 提供了一个可伸缩、可扩展的平台,为虚拟化管理奠定了基础。可集中管理VMware vSphere环境,与其他管理平台相比,极大地提高了 IT 管理...
  • ccityy
  • ccityy
  • 2016-12-31 14:27:12
  • 62004

VMware 12 安装Ubuntu 16.04 (图文教程)

1 环境准备: (1) 原系统为WIN8,已正确安装虚拟机VMware Workstation Pro. (2) 下载Ubuntu系统 a. 进入链接http://www.ubuntu.org....
  • colin_lisicong
  • colin_lisicong
  • 2017-04-16 07:09:26
  • 21049

VMware中linux访问共享文件夹设置流程

最近在学习嵌入式系统,师兄让从linux系统开始抓起,于是乎我就开始了“闹心”的linux之旅。由于要学习制作嵌入式系统的根文件系统,需要在linux系统中访问window目录下的...
  • mountzf
  • mountzf
  • 2016-05-26 01:27:31
  • 10816

VMware12的下载和安装

1      VMware的下载 下载地址:云盘下载:http://pan.baidu.com/s/1o67s0UQ 官网下载:https://my.VMware.com 这里我们使用的是:VMwar...
  • tian_li
  • tian_li
  • 2015-10-05 12:38:57
  • 2785

安装VMware Workstation 10

一、下载VMware 10 百度云:http://pan.baidu.com/s/1yNuKQ 提取码:y4q3 注意:如果链接不可用,可以私信找我要,也可以自行Google 二、安装...
  • Geek_Geek
  • Geek_Geek
  • 2015-07-09 08:42:06
  • 1676

VMware 下 Ubuntu 使用 Share folder 共享 WIN7 文件

一、摘要 该文主要介绍了如何在虚拟机上安装ubuntu,和安装VMWare Tools设置共享文件夹,最后对ubuntu做了简单的介绍。   二、实验平台 1、VMware W...
  • NarutoInspire
  • NarutoInspire
  • 2016-05-14 16:21:06
  • 3616

VMware V12.0.1 专业版 + 永久密钥

热门虚拟机软件VMware Workstation 现已更新至v12.0.1 专业版!12.0属于大型更新,专门为Win10的安装和使用做了优化,支持DX10、4K高分辨率显示屏、OpenGL 3.3...
  • u011431550
  • u011431550
  • 2016-03-05 13:18:36
  • 1020
    个人资料
    专栏达人 持之以恒 博客之星
    等级:
    访问量: 110万+
    积分: 1万+
    排名: 1265
    博客专栏
    最新评论
    公众号
    Python笔试面试公众号