在介绍cow与raw格式前,先看如下操作,通过ll -l与 du 查看一个磁盘镜像的大小,结果如下
[root@localhost d9907fa5-641b-4d52-80e6-c8c5262f6f94]# ll -l cbbb29b4-cd7f-4a12-ace7-ecfe39158cf8
-rw-rw----. 1 vdsm kvm 1073741824 Nov 2 09:18 cbbb29b4-cd7f-4a12-ace7-ecfe39158cf8
[root@localhost d9907fa5-641b-4d52-80e6-c8c5262f6f94]# du -s cbbb29b4-cd7f-4a12-ace7-ecfe39158cf8
0 cbbb29b4-cd7f-4a12-ace7-ecfe39158cf8
ll 显示的是1G,而du显示的是0。
这与我们通常的理解有点偏差,一般我们会认为ls的结果会比du的结果要小一点。因为占用空间取决于文件系统的块(block)的大小,linux一般默认是4k(4096),因此,一个大小为1个字节的文件,最小也要占用4k,如果你创建文件系统的时候制定块大小是16K,那么即便一个文件只有1个字节,占用空间也是16K。而 du显示的size是文件在硬盘上占据了多少个block计算出来的。ls显示文件的“逻辑上”的size,而du显示文件“物理上”的size。不过注意的是 ls -s 执行的效果与du一样,反应磁盘分配情况,非实际文件大小,以block为单位,ls -s == du。如下,ll 反应的大小为"逻辑"占用的大小, 而du反应的"物理"上的大小。
写一个字符到一个文件中,看其大小
[root@localhost d9907fa5-641b-4d52-80e6-c8c5262f6f94]# echo -n 1 > 1B.txt
[root@localhost d9907fa5-641b-4d52-80e6-c8c5262f6f94]# ll 1B.txt
-rw-r--r--. 1 root root 1 Nov 2 09:47 1B.txt
[root@localhost d9907fa5-641b-4d52-80e6-c8c5262f6f94]# du -s 1B.txt
4 1B.txt
大家现在有点疑惑了,那到底是怎么一回事呢?
虚拟机镜像文件保存了虚拟机硬盘的全部信息,按照数据存储方式的不同,可以分为两种模式:全镜像模式(FlatMode)和稀疏模式(SparseMode)。全镜像模式保存了虚拟硬盘中的所有字节数据,其中也包括对用户而言无效的数据;raw格式就是全镜像模式。稀疏模式只保存对用户和文件系统有效的数据,只占用必要的存储空间,这种模式的镜像文件在存放数据时使用的可能不是连续的物理磁盘空间;
接着分析,上面图1的结果,因为磁盘格式是raw的,但是其type是 sparse,也就是稀疏文件。稀疏文件指文件中有“洞”(hole)的文件。我们通过qemu 中提供的工具查看该磁盘的信息。如下, ls看到就是 virtual size,而du看到的是磁盘的大小。
[root@localhost d9907fa5-641b-4d52-80e6-c8c5262f6f94]# qemu-img info cbbb29b4-cd7f-4a12-ace7-ecfe39158cf8
image: cbbb29b4-cd7f-4a12-ace7-ecfe39158cf8
file format: raw
virtual size: 1.0G (1073741824 bytes)
disk size: 0
同样我们对这个磁盘进行 cp 和scp 的操作是不一样的,cp后的结果是原磁盘一样。而scp 到另一台主机时,则目标大小du后也实际占用1G。这就是背后的实现不一样。看cp的源代码,我们发现每次read之后,cp会判断读到的内容是不是都是0,如果是就只lseek而不write。
接下来 我们分析下磁盘格式 raw与qcow2
raw
就是原始的,它直接将文件系统的存储单元分配给虚拟机使用,采取直读直写的策略。在raw格式的文件中,虚拟出来的磁盘数据块号的大小决定了该数据块在raw文件中的偏移量,也就是说虚拟磁盘存放数据的顺序和raw文件中存放数据的顺序是一致的,由于这个特性,VBA到IBA的转换比较简单,而IBA实际上就是PBA。在很多的实际应用中,模板镜像采用raw格式,以提高模板镜像的读性能,而增量镜像则使用其他格式,方便支持其他辅助特性。raw格式的优点有:一是寻址简单,访问效率较高;二是可以通过格式转换工具方便地转换为其他格式;三是可以方便地被宿主机挂载,可以在不启动虚拟机的情况下和宿主机进行数据传输。但是,由于raw格式实现简单,不支持诸如压缩、快照、加密和CoW等特性,另外,raw格式文件在创建时指定大小之后,就占用了宿主机指定大小的空间,而不像qcow2等稀疏模式的镜像格式可以从很小的文件按需地增长。
可以通过 dd 或者qemu-img生成 raw格式的磁盘,但是type为全镜像模式的磁盘则占据
[root@node c5cfe9f8-1560-4f3c-ba0c-02645267dc7c]# qemu-img create -f raw qemu.raw 10G
Formatting 'qemu.raw', fmt=raw size=10737418240
[root@node c5cfe9f8-1560-4f3c-ba0c-02645267dc7c]# dd if=/dev/zero of=dd.img bs=1M seek=1000 count=0
0+0 records in
0+0 records out
0 bytes (0 B) copied, 0.000244183 s, 0.0 kB/s
[root@node c5cfe9f8-1560-4f3c-ba0c-02645267dc7c]# qemu-img info dd.img
image: dd.img
file format: raw
virtual size: 1.0G (1048576000 bytes)
disk size: 0
[root@node c5cfe9f8-1560-4f3c-ba0c-02645267dc7c]#
[root@node c5cfe9f8-1560-4f3c-ba0c-02645267dc7c]# qemu-img info qemu.raw
image: qemu.raw
file format: raw
virtual size: 10G (10737418240 bytes)
disk size: 0
cow
目前主流的一种虚拟化镜像格式,经过qcow的优化,目前qcow2的性能上接近raw裸格式的性能。对于qcow2的格式,几点还是比较突出的,qcow2的snapshot,可以在镜像上做N多个快照: 更小的存储空间,即使是不支持holes的文件系统也可以(这下du -h和ls -lh看到的就一样了)。支持多个snapshot,对历史snapshot进行管理 支持zlib的磁盘压缩 支持AES的加密。
qcow2 镜像可以用来保存另一个镜像文件的变化,它并不去修改原始镜像文件,只记录与原始镜像文件的不同即可,这种镜像文件就叫做 copy-on-write 镜像。虽然是一个单独的文件,但它的大部分的数据都来自原始镜像,只有跟原始镜像文件相比有变化的 cluster 才会被记录下来。这很容易去实现,在头部信息中记录原始文件路径即可。当需要从一个 copy-on-write 镜像文件中读取一个 cluster 的时候,首先检查这块区域是否已经在该镜像文件中被分配,如果没有就从原始文件读取。
我们对type为sprase的raw格式的磁盘创建快照后,生成的磁盘就是qcow2格式的。
[root@localhost d9907fa5-641b-4d52-80e6-c8c5262f6f94]# qemu-img info 9db30237-d00c-4982-8eb2-f5d2430ca270
image: 9db30237-d00c-4982-8eb2-f5d2430ca270
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 196K
cluster_size: 65536
backing file: ../d9907fa5-641b-4d52-80e6-c8c5262f6f94/cbbb29b4-cd7f-4a12-ace7-ecfe39158cf8
backing file format: raw
Format specific information:
compat: 0.10
总结:
性能来说,raw的格式总体要好一些,但是不具备qcow2的一些辅助特性,如快照、加密等。
https://www.ibm.com/developerworks/cn/linux/1409_qiaoly_qemuimgages/
http://czmmiao.iteye.com/blog/1748748 dd命令
http://smilejay.com/2012/08/qemu-img-details/ qemu-img详解
http://wenku.baidu.com/link?url=9epNm6hWBArsIqtxSnMTtJ1-VNZBFK4vejjcFKTLly_N_ZJavW8jtOVmGndXmnH4VTBZuIzYtQ1npst09t8eVNOCXg4-ZMoRU3A4cDDkEpu