本文英文出处:Sébastien Han/ceph-and-krbd-discard
内核RBD模块的空间回收机制。对于运营商而言,有这样的支持是至关重要的,因为这能减轻你的容量规划。RBD镜像是稀疏的,因此创建后大小等于0 MB。稀疏镜像的主要问题在于增长,最终达到整个镜像的大小。问题是这是发生在块层面之上尤其是其上有文件系统的时候Ceph并不知道发生了什么。你可以很容易地向整个文件系统写入数据,然后删除一切,但是Ceph仍然相信这些块仍然被使用着,并持续度量。然而多亏在块设备层面支持了 discard,文件系统可以发送 discard flush 命令给块。最后,存储系统将释放这些上层已经删除的块。
这个特性自3.18版本的内核开始引入。
我们先新建一个 RBD 镜像
1 | $ rbd create -s 10240 leseb |
将它映射到一个节点并在其上构建一个文件系统:
1 | $ sudo rbd -p rbd map leseb |
到这里所有的设置都已经完成,我们开始写入一些数据:
1 | $ dd if=/dev/zero of=/mnt/leseb bs=1M count=128 |
然后我们再次检测这个镜像占用的空间大小:
1 | $ rbd diff rbd/leseb | awk '{ SUM += $2 } END { print SUM/1024/1024 " MB" }' |
我们知道这里我们实际的数据是 128MB,文件系统的数据/元数据占用了约 ~14,406MB。检查这个份设备的 discard 属性已经启用:
1 | root@ceph-mon0:~# cat /sys/block/rbd0/queue/discard_* |
现在让我们来检查当 discard 不支持时的默认行为,我们删除前面新建的所有 128MB 的文件以释放文件系统的一些空间。不幸的是Ceph什么也没检测到,仍然认为这 128MB 的数据仍然存在。
1 | $ rm /mnt/leseb |
现在让我们在挂载的文件系统上运行 fstrim 命令以指示块设备释放未使用的空间:
1 | $ fstrim /mnt/ |
Et voilà ! Ceph 释放了我们删除的 128 MB。
如果你想自动运行 discard,可以在挂载文件系统的时候加上 discard 选项,这样就可以让文件系统一直检测 discard:
1 | $ mount -o discard /dev/rbd0 /mnt/ |
注意,使用 discard 的挂载选项会严重影响性能。所以,一般你可以通过一个每天与星的 cron 任务来触发 fstrim 命令。
译者补充:
我的实际线上环境是:ubuntu12.04+Ceph 0.67.9
同时对于使用 KRBD 的都有感触,要保障业务不断的同时进行升级是相当麻烦的,但是这个存储系统已经稳定运行两年,Ceph检测到已用空间到了70%,但是实际业务系统层面统计还不到50%,因此执行 fstrim 势在必行。
经过本文作者的提示,我们的方案是在这个集群上使用kvm新建一个 ubuntu14.04.4 的虚拟机,依次将所有 RBD 在该虚拟机上映射后挂载到某一个目录,然后在这个目录上执行 fstrim 命令,达到清理的目的。
这个方案有需要注意:
推荐的步骤是原挂载点先 umount ,再在该虚拟机上mount再执行fstrim。(原来的做法没有在原挂载点先umount,而是同一个 RBD 在两个不同节点映射并挂载,这样做存在新写入数据丢失的风险,一部分块被标记删除但是此时又有新数据写入就会有这种风险,再具体的需要对rbd的fstrim的机制进一步深入分析才能确认,再次感谢微信群 Ceph中国社区 的大牛 陈晓熹 的指点。;