天天看点

虚拟机建立快照_虚拟机的快照功能是如何实现的?

泻药

题主很仔细,快照确实是虚拟化很棒的一个技术特性,现在物理机角度理解它确实不太容易,我尝试白话解释下原理。

首先,虚拟机和物理机显著的不同是我们看待一台虚拟机是当成文件处理的,理解了这点,下面的问题就好理解了

先说建立快照,实质的过程把当前的内存状态打个标签写入硬盘的过程,这两部都很简单,就像是git的add .和commit一样存档而已,唯一的不同是,这个写入硬盘的过程是除了一个几k的标签外,不产生任何新文件的,并不是想象中的把当前文件另存为新文件,然后再有个专门的标签索引器来做时光穿梭,就像是:

原来硬盘里:

a (a).current

加载到内存里:

a

内存里写点东西:

abc

快照后内存里:

abc

快照后硬盘里

abc _abc.tag (abc).current

这里面abc是那个只增不减的块文件, (abc).current是当前的虚拟机文件状态标签,_abc.tag只是从(abc).current复制出来的一个存档小标签。

然后快照完继续操作虚拟机,这个过程叫copyonwrite但是直译过来并不直观,[email protected]的意思是指,不论你将来怎么对这个文件进行修改,都只能对文件是增量修改而已,写入过程不会造成旧档丢失,除非你快照删掉,才会把快照关键的存档连带去掉。

比如你添加d删除a

修改前硬盘:

abc _abc.tag (abc).current

加载到内存:

abc

添d删a:

bcd

写入硬盘后:

abcd _abc.tag (bcd).current

如果在这个基础上也做快照的话

内存里:

bcd

快照后内存里:

bcd

快照后硬盘里:

abcd _abc.tag _bcd.tag (bcd).current

因此你可以看到那个abcd是基本只增不减的块文件,而你读出虚拟机读的是那个.current的当前状态,所有的打快照都是从.current存下的小tag而已,因此做快照很快。

下面说读取快照,这就简单了,加载 _abc.tag 看看它对应abcd里对应了哪些部分,加载出来,释放到内存里,这个过程时间,因为当前内存里是加载的 (bcd).current,两块而内存里东西不一样,要有个替换的过程,所以耗时一点。

而删除快照,就稍微复杂了一点,其实理论上你删除任何快照速度取决于,这个要删除的快照对那个最大的块文件影响大小。

比如你想删除_abc.tag这个快照,那么也就意味着,之前abc里的所有改动你不需要了,所以那个块文件就要删除掉那个a,总的块文件占空间就会更小一点,过程如下:

删除前硬盘

abcd _abc.tag _bcd.tag (bcd).current

删除_abc.tag这个快照

abcd _bcd.tag (bcd).current

系统看到你删除了_abc.tag这个快照,于是把块文件的a也要操作删除

bcd _bcd.tag (bcd).current

最终:

bcd _bcd.tag (bcd).current

这里这个a部分变动越大,删除就越慢。

所以你做快照,不过就是留tag而已,然后把快照的老数据也留下来,所以做快照不会让使用空间几何倍的被占用,改动都是增量的,但是你在虚拟机里删除文件,由于有老快照牵连着,空间也不会变小,除非删除快照。

快照多了,理论上不会对虚拟机性能造成影响,但是毕竟.current要在一个相对更复杂的环境里索引,如果hypervisor层软件本身质量不佳的话这个就不好说了。

以上是原理举例,不对应具体文件名和格式啊,领会精神,恩,领会精神。