Chinaunix首页 | 论坛 | 博客
  • 博客访问: 272285
  • 博文数量: 56
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 642
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-16 15:11
文章分类

全部博文(56)

文章存档

2017年(6)

2015年(3)

2014年(41)

2013年(6)

我的朋友

分类: LINUX

2014-10-01 19:49:41

discard是什么?
 
在SSD出现之后,产生了一个问题:由于SSD底层的存储实现上和传统的机械硬盘截然不同,导致两者在数据写入和删除上表现出了极大的差异,传 统机械硬盘删除数据时仅仅需要将元数据标记为删除,而真正的数据block实际上并没有立即被删除,当下一次写入数据时,只需要用新的数据覆盖掉旧的数据 即可。而SSD则不一样,新的数据只能往空白区域写入,不能像机械硬盘那样直接覆盖,因此一次覆盖写操作将变成一个 read-erase-modify-write 的循环,操作系统如果还是按照机械硬盘的覆盖写入方式来操作SSD的话,将带来性能上的大打折扣和硬盘使用寿命的缩短。因此对于SSD的操作人们提出了新 的需求——需要在数据删除的时候通知硬盘,将数据立即清理掉,在这种需求下,trim指令[1]诞生了,trim指令允许操作系统在SSD上将不再使用的 数据通知到SSD底层并在其内部将数据擦除掉。

在虚拟化技术的磁盘虚拟化中,也出现了类似问题:由于虚拟磁盘与物理机械硬盘的差异,导致操作系统如果还是按照机械硬 盘的方式来删除虚拟磁盘的数据的话,会出现一些额外的效果。通常我们都希望thin providing的磁盘设备容量用多少算多少,但是现实往往不尽如人意,当我们往虚拟磁盘中写入100M数据,再将它删除,再写入100M数据,我们希 望看到的结果是,虚拟磁盘占用不超过100M容量大小,但是现实是虚拟磁盘占用了超过100M容量。这是因为当我们在虚拟机内部执行了删除操作时,如果还 是按照机械硬盘的删除方式,那么真正占用了磁盘空间的block部分并没有立即被释放,如果我们在虚拟机内部不断地进行write-delete 循环的话,虚拟磁盘文件将越来越大,大到甚至超过了额定预分配大小。人们开始意识到在这种虚拟化场景下类似于SSD的trim指令所提供的功能也仍然适 用,对于节省存储开销有积极意义。因此,与trim类似的指令也出现在了虚拟磁盘中,用在scsi接口虚拟磁盘上的这个指令叫unmap,通常我们把trim和unmap指令提供的功能称之为discard。

哪些版本支持discard?
 
内核对discard的支持早在2.6.33中就被包含进来,在RHEL6中我们可以发现在2.6.32版本的内核包就将这个功能backport进来,用户空间的程序开始支持discard要稍微晚一些,qemu在1.5版本开始支持(), libvirt从1.0.6开始支持()。这两个项目的discard功能支持都是由Red Hat提交的,其中libvirt的discard支持是由负责的,他是兰大开源社区的创始人之一。
 
我们可以看看当前最新的fedora20中的版本情况:

																
								
[root@localhost ~]$ rpm -q qemu-kvm
qemu-kvm-1.6.2-1.fc20.x86_64
[root@localhost ~]$ rpm -q libvirt-daemon
libvirt-daemon-1.1.3.4-4.fc20.x86_64
 
如何使用discard?
 
要启用虚拟机的discard功能我们只需要在确保当前系统版本支持的基础上,进行两方面的配置即可,一是在host machine上通过libvirt修改虚拟机配置添加disk driver的相关支持,注意下面的配置示例中将使用virtio-scsi作为虚拟磁盘驱动,且添加了额外的' discard="unmap" '






另一方面我们需要在虚拟机system内修改磁盘的挂载参数以增加对discard的支持:
mount -o discard 
或者使用fstrim命令来一次性触发discard操作:
fstrim /mntpoint
 
 
如何验证discard是否有效?
 
我们可以通过下面这个简单的对比实验来观察discard的效果,首先为虚拟机分配两块磁盘,sda设置为支持discard而sdb不设置










接着启动虚拟机,将两块磁盘分区格式化文件系统后分别挂载到/sda和/sdb目录,对于两个目录均执行循环写入和删除数据的操作,
#mount -o discard /dev/sda1 /sda
#mount /dev/sdb1 /sdb
#for _ in {1..3}; do
dd if=/dev/urandom of=/sda/file.$RANDOM bs=1M count=100 && sync
dd if=/dev/urandom of=/sdb/file.$RANDOM bs=1M count=100 && sync
rm -f /sda/file.* /sdb/file.* && sync
done

现在回到host machine中,使用du命令来观察两个虚拟磁盘的占用容量大小情况:
$du -h sd{a,b}.img
34M sda.img
138M sdb.img

此时discard的好处显而易见,启用了discard功能的sda消耗的存储容量要比没有启用的sdb小得多。


libvirt/qemu 文件系统trim

目前virtio驱动无法支持trim,ide/scsi/virtio-scsi驱动可以支持trim。
qemu的trim特性:1.5版支持raw,1.6版支持qcow2。
NTFS本身支持trim命令,EXT4需要在mount时指定参数-o discard,EXT3需要手工执行fstrim。

  • libvirt方式启动虚拟机 ide为例:
     type='file' device='disk'>   name='qemu' type='qcow2' cache='none' discard='unmap'/>  file='/data/hotplug/vdb.qcow2'/>   dev='sdb' bus='ide'/>  

virtio-scsi为例:

  type='file' device='disk'>  file='/tmp/scsidisk.qcow2'/>  dev='sda' bus='scsi'/>  type='drive' controller='0' bus='0' target='0' unit='0'/>    type='scsi' index='0' model='virtio-scsi'/>   
  • qemu直接启动虚拟机
./qemu-system-x86_64 --enable-kvm -m 2g -smp 2  -drive file=/data/hotplug/hotplug.qcow2,cache=none,if=ide,discard=on,format=qcow2 -drive file=/data/hotplug/vdb.qcow2,cache=none,if=ide,discard=on,format=qcow2  -vnc 186.100.8.138:-1 

新格式(以virtio-scsi-pci为例):

./qemu-system-x86_64 --enable-kvm -m 2g -smp 2  -drive file=/data/hotplug/hotplug.qcow2,cache=none,if=none,id=hd2,discard=on,format=qcow2 -drive file=/data/hotplug/vdb.qcow2,cache=none,if=none,id=hd,discard=on,format=qcow2 -device virtio-scsi-pci,id=scsi -device scsi-hd,drive=hd2 -device scsi-hd,drive=hd   -vnc 186.100.8.138:-1 
  • 确认方法
    虚拟机内部(文件系统挂载需要-o discard参数):
mount -o discard /dev/sdb /mnt 

在guest中/mnt下创建大文件:

[root@localhost hotplug]# du -hs vdb.qcow2
481M    vdb.qcow2 

在guest中/mnt下删除大文件:

[root@localhost hotplug]# du -hs vdb.qcow2
294M    vdb.qcow2 
阅读(7189) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

yangyangRH2014-10-01 21:48:54

http://raobharata.wordpress.com/2013/08/07/unmapdiscard-support-in-qemu-glusterfs/

yangyangRH2014-10-01 21:21:08

http://leiqzhang.com/2013/08/2013-08-07-virtual-disk-unmap-shrink/