1.問題描述
在OpenStack云環(huán)境的部署中,存儲(chǔ)通常具備Thin provision的功能,這項(xiàng)功能實(shí)現(xiàn)了存儲(chǔ)按需分配的能力?,F(xiàn)在有這樣一種場(chǎng)景,用戶在文件系統(tǒng)中創(chuàng)建了大文件,使用完之后進(jìn)行了刪除。但實(shí)際上,該文件在存儲(chǔ)系統(tǒng)上占用的空間并沒有釋放。
當(dāng)用戶在文件系統(tǒng)中刪除一個(gè)文件,并不會(huì)在塊設(shè)備上的對(duì)應(yīng)空間填0,而僅僅在磁盤的元數(shù)據(jù)結(jié)構(gòu)中將這些block標(biāo)記為未使用。因此,雖然文件系統(tǒng)知道這些block是未使用或者說可用的,但是底層的存儲(chǔ)系統(tǒng)并不知道文件系統(tǒng)做的操作,會(huì)認(rèn)為這些block仍在使用。以RBD image為例,它本身是稀疏格式的,也就是說它所占用objects會(huì)隨著用戶寫入數(shù)據(jù)的增加而增加(Thin provision)。當(dāng)用戶刪除數(shù)據(jù)以后,這些obejct不再使用,但并沒有被釋放。因?yàn)閺腃eph的角度講,它并不知道文件系統(tǒng)中發(fā)生的事情。
2.解決辦法
需要配置Nova和Glance支持virtio-scsi和discard。
1、glance image-update --property hw_scsi_model=virtio-scsi --property hw_disk_bus=scsi
其中,hw_scsi_model=virtio-scsi 是指libvirt要使用virtio-scsi控制器,hs_disk_bus=scsi是指libvirt使用scsi總線連接磁盤到控制器。
2、編輯nova.conf
[libvirt]
hw_disk_discard = unmap
其中,有效的hw_disk_discard參數(shù)包括:
unmap: it unmaps aligned group of sectors
ignore: it ignores the discard request
2.1 觸發(fā)Trim/Discard請(qǐng)求
有兩種方式可以觸發(fā)Trim/Discard請(qǐng)求,一種是由文件系統(tǒng)自動(dòng)完成,一種是用戶通過執(zhí)行命令來完成。
一、文件系統(tǒng)自動(dòng)完成
只要在掛載文件系統(tǒng)時(shí)指定discard參數(shù)即可,比如 mount -t ext4 -o discard? device mountpoint,這樣在文件系統(tǒng)中刪除文件后會(huì)自動(dòng)觸發(fā)Trim/Discard操作,在塊設(shè)備上釋放占用的空間。
二、用戶執(zhí)行命令
用戶可以執(zhí)行命令fstrim來觸發(fā)Trim/Discard操作,采用這種方式mount文件系統(tǒng)時(shí)不需要discard參數(shù)。比如,fstrim -v mountpoint,就會(huì)釋放對(duì)應(yīng)塊設(shè)備上不用的空間。
需要注意的是,mount的discard參數(shù)會(huì)導(dǎo)致文件系統(tǒng)性能下降,在并發(fā)刪除大量小文件時(shí)變得很慢,因此需要根據(jù)具體場(chǎng)景選擇合適的長(zhǎng)發(fā)方式。
2.2 系統(tǒng)盤加discard
不能通過重新掛載設(shè)置丟棄選項(xiàng),因此必須在第一次掛載時(shí)使用它(如果是/,則是在引導(dǎo)時(shí)由內(nèi)核掛載rootfs)。關(guān)鍵是使用rootflags來提供discard mount選項(xiàng)作為內(nèi)核參數(shù)
在/boot/grub2/grub.cfg文件中,增加rootflags=discard