rbd做快照克隆以后的容量相关问题

背景

rbd的做快照,然后克隆,原始设备可以变成两个设备供客户端使用,占用的空间为1份,这个是在没有新写入情况下的容量占用情况
那么如果有新写入的的数据之后,这个地方容量是怎么去看的,以及在出现写入又删除的情况下,rbd的实际占用空间又是如何释放的

相关测试操作

快照后的容量占用

我们先准备一个rbd的设备,并且格式化为ntfs的文件系统,然后写入一个大文件为2.4G的
我们看下容量占用情况

1
2
3
4
5
6
7
8
[root@lab101 ~]# rbd du gamebase
NAME PROVISIONED USED
gamebase 30 GiB 2.4 GiB

[root@lab101 ~]# ceph df
--- POOLS ---
POOL ID PGS STORED OBJECTS USED %USED MAX AVAIL
rbd 9 32 2.4 GiB 631 2.4 GiB 3.22 73 GiB

占用就是这么多,我们再做一个快照

1
2
[root@lab101 ~]# rbd snap create --image gamebase --snap gamesnap1
[root@lab101 ~]# rbd snap protect --image gamebase --snap gamesnap1

再看占用情况

1
2
3
4
5
6
7
8
9
[root@lab101 ~]# rbd du gamebase
NAME PROVISIONED USED
gamebase@gamesnap1 30 GiB 2.4 GiB
gamebase 30 GiB 0 B
<TOTAL> 30 GiB 2.4 GiB
[root@lab101 ~]# ceph df
--- POOLS ---
POOL ID PGS STORED OBJECTS USED %USED MAX AVAIL
rbd 9 32 2.4 GiB 632 2.4 GiB 3.22 73 GiB

可以看到gamebase那里的显示是0,因为做了快照,那么做快照的那一刻以后再写入的数据,就是gamebase的写入,做了快照的部分是不变化的了,因为快照的内容是可以恢复的,所以这里肯定就是固定住的

这里我们使用ceph的内部的一个清理0空间的命令做一个操作看下

sparsify操作引起的显示偏差

1
2
[root@lab101 ~]# rbd sparsify rbd/gamebase
Image sparsify: 100% complete...done.

我们查看下容量

1
2
3
4
5
6
7
8
9
10
[root@lab101 ~]# rbd du gamebase
NAME PROVISIONED USED
gamebase@gamesnap1 30 GiB 2.4 GiB
gamebase 30 GiB 2.4 GiB
<TOTAL> 30 GiB 4.9 GiB
[root@lab101 ~]# rbd du gamebase --exact
NAME PROVISIONED USED
gamebase@gamesnap1 30 GiB 2.4 GiB
gamebase 30 GiB 20 MiB
<TOTAL> 30 GiB 2.4 GiB

可以看到,gamebase里面统计的值出现了很大的情况,这个值,直接就是把快照的值基本一样

1
2
3
4
[root@lab101 ~]# ceph df
--- POOLS ---
POOL ID PGS STORED OBJECTS USED %USED MAX AVAIL
rbd 9 32 2.4 GiB 640 2.4 GiB 3.23 73 GiB

但是实际并没有对集群进行空间的占用,所以这里注意下,这个sparsify除非底层真的有0空间的对象,否则的话没必要做,会造成这个地方的显示差别,有参数可以排除这个差异,这里知道操作能够引起这个显示的差别即可,这个地方有正常的统计的方法即可,里面涉及到底层的一些不同的计算逻辑,我们继续后面的,环境先恢复为没有做sparsify前

1
2
3
4
5
[root@lab101 ~]# rbd snap unprotect --image gamebase --snap gamesnap1
[root@lab101 ~]# rbd snap rm --image gamebase --snap gamesnap1
Removing snap: 100% complete...done.
[root@lab101 ~]# rbd snap create --image gamebase --snap gamesnap1
[root@lab101 ~]# rbd snap protect --image gamebase --snap gamesnap1

windows的trim触发进行空间回收

我们克隆一个镜像

1
[root@lab101 ~]# rbd clone --image gamebase --snap gamesnap1  gameclone1

我们在windows下面直接使用这个镜像,通过windows的rbd的功能

启用.NET Franework 3.5功能

windows下面使用wnbd要注意(powershell操作)

1
2
Confirm-SecureBootUEFI
bcdedit.exe /set testsigning yes

一个确认关闭了安全启动
一个是进入测试模式,也就是关闭了签名认证类的,否则安装报错

安装包的地址

https://cloudba.se/ceph-win-latest-pacific

win10版本也注意下,我测试了几个版本不行,需要用win10 22H2版本的才能正常安装

windows的ceph配置文件
配置文件的路径 C:\ProgramData\Ceph\ceph.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[global]
log to stderr = true
auth_cluster_required = none
auth_service_required = none
auth_client_required = none
; Uncomment the following in order to use the Windows Event Log
; log to syslog = true

run dir = C:/ProgramData/Ceph/out
crash dir = C:/ProgramData/Ceph/out

; Use the following to change the cephfs client log level
; debug client = 2
[client]
; keyring = C:/ProgramData/Ceph/keyring
; log file = C:/ProgramData/ceph/out/$name.$pid.log
;admin socket = C:/ProgramData/Ceph/out/$name.$pid.asok

; client_permissions = true
; client_mount_uid = 1000
; client_mount_gid = 1000
[global]
mon host = 192.168.0.101

挂载rbd的命令

1
rbd-wnbd.exe -c C:\ProgramData\Ceph\ceph.conf map rbd/gameclone1

卸载rbd的命令

1
rbd-wnbd.exe -c C:\ProgramData\Ceph\ceph.conf unmap rbd/gameclone1

注意操作后去磁盘管理里面看看,进行联机操作后,盘符可以识别

检查下容量

1
2
3
4
5
6
7
8
[root@lab101 ~]# rbd du gamebase
NAME PROVISIONED USED
gamebase@gamesnap1 30 GiB 2.4 GiB
gamebase 30 GiB 0 B
<TOTAL> 30 GiB 2.4 GiB
[root@lab101 ~]# rbd du gameclone1
NAME PROVISIONED USED
gameclone1 30 GiB 32 MiB

我们往gamebase和gameclone里面都写入一个400MB文件,看下容量占用情况

1
2
3
4
5
6
7
8
9
10
11
12
[root@lab101 ~]# rbd du gameclone1
NAME PROVISIONED USED
gameclone1 30 GiB 448 MiB
[root@lab101 ~]# rbd du gamebase
NAME PROVISIONED USED
gamebase@gamesnap1 30 GiB 2.4 GiB
gamebase 30 GiB 436 MiB
<TOTAL> 30 GiB 2.9 GiB
[root@lab101 ~]# ceph df
--- POOLS ---
POOL ID PGS STORED OBJECTS USED %USED MAX AVAIL
rbd 9 32 3.2 GiB 856 3.2 GiB 4.31 72 GiB

可以看到容量都是正常的,我们再删除刚刚写入的文件

1
2
3
4
5
6
7
8
9
10
11
12
[root@lab101 ~]# rbd du gamebase
NAME PROVISIONED USED
gamebase@gamesnap1 30 GiB 2.4 GiB
gamebase 30 GiB 436 MiB
<TOTAL> 30 GiB 2.9 GiB
[root@lab101 ~]# rbd du gameclone1
NAME PROVISIONED USED
gameclone1 30 GiB 448 MiB
[root@lab101 ~]# ceph df
--- POOLS ---
POOL ID PGS STORED OBJECTS USED %USED MAX AVAIL
rbd 9 32 3.2 GiB 856 3.2 GiB 4.31 72 GiB

可以看到容量没有发生任何变化,这里我们忽略了windows的一个问题,问题有回收站,所以回收站需要清理文件才是真正的删除,否则只是隐藏了而已

清空回收站后再看容量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@lab101 ~]# rbd du gamebase
NAME PROVISIONED USED
gamebase@gamesnap1 30 GiB 2.4 GiB
gamebase 30 GiB 32 MiB
<TOTAL> 30 GiB 2.5 GiB
[root@lab101 ~]# rbd du gamebase --exact
NAME PROVISIONED USED
gamebase@gamesnap1 30 GiB 2.4 GiB
gamebase 30 GiB 2.5 MiB
<TOTAL> 30 GiB 2.4 GiB
[root@lab101 ~]# rbd du gameclone1
NAME PROVISIONED USED
gameclone1 30 GiB 448 MiB
[root@lab101 ~]# rbd du gameclone1 --exact
NAME PROVISIONED USED
gameclone1 30 GiB 27 MiB
[root@lab101 ~]# ceph df
--- RAW STORAGE ---
CLASS SIZE AVAIL USED RAW USED %RAW USED
hdd 80 GiB 77 GiB 2.5 GiB 3.5 GiB 4.37
TOTAL 80 GiB 77 GiB 2.5 GiB 3.5 GiB 4.37

--- POOLS ---
POOL ID PGS STORED OBJECTS USED %USED MAX AVAIL
rbd 9 32 2.4 GiB 755 2.4 GiB 3.24 73 GiB

可以看到,gameclone1和gamebase写入后有删除的文件,在后台都得到了空间释放,这个地方是windows自动做了trim操作,并且我们可以看到gameclone1这里不带参数的查询,显示的还是之前的那个文件大小448MB,看上去没有释放,但是用exact查询和ceph df可以看到容量其实是真正释放了

全盘trim会引起底层空对象

windows的trim触发默认是文件级别的触发的,可以看到,我们再调用下磁盘级别的trim看下变化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
PS C:\Windows\system32> Optimize-Volume -DriveLetter G -ReTrim -Verbose
详细信息: 正在调用 新加卷 (G:) 上的 重新剪裁...
详细信息: 正在执行传递 1:
详细信息: 重新剪裁: 0% 完成...
详细信息: 重新剪裁: 7% 完成...
详细信息: 重新剪裁: 10% 完成...
详细信息: 重新剪裁: 16% 完成...
详细信息: 重新剪裁: 33% 完成...
详细信息: 重新剪裁: 50% 完成...
详细信息: 重新剪裁: 66% 完成...
详细信息: 重新剪裁: 86% 完成...
详细信息: 重新剪裁: 100% 完成。
详细信息:
Post Defragmentation Report:
详细信息:
卷信息:
详细信息: 卷大小 = 29.98 GB
详细信息: 簇大小 = 4 KB
详细信息: 已用空间 = 2.43 GB
详细信息: 可用空间 = 27.54 GB
详细信息:
重新剪裁:
详细信息: 支持的分配 = 30
详细信息: 已整理的分配 = 27
详细信息: 已整理的空间总计 = 26.54 GB

检查容量情况

1
2
3
4
5
6
7
8
9
10
[root@lab101 ~]# rbd du gameclone1
NAME PROVISIONED USED
gameclone1 30 GiB 27 GiB
[root@lab101 ~]# rbd du gameclone1 --exact
NAME PROVISIONED USED
gameclone1 30 GiB 38 MiB
[root@lab101 ~]# ceph df
--- POOLS ---
POOL ID PGS STORED OBJECTS USED %USED MAX AVAIL
rbd 9 32 2.5 GiB 7.50k 2.4 GiB 3.26 72 GiB

可以看到那个使用USED的地方变成了27GB,这个地方是全盘的trim触发的,相当于用0空间去全部占用了,然后又全部进行了统计了,那个exact的就是会真实去计算空间占用,这个地方还有个地方变化比较大,可以看到objects变成了7.5K,也就是这个镜像全部的对象都进行了分配并且是0空间的

查看windows是否开启了trim的命令

1
2
3
PS C:\Windows\system32> fsutil behavior query DisableDeleteNotify
NTFS DisableDeleteNotify = 0 (已禁用)
ReFS DisableDeleteNotify = 0 (已禁用)

显示为上面的情况就是开启了的,默认是开启了trim的

总结

上面做了一些测试,我们来进行一下总结

  • 1、如果image做了快照,那么容量显示就会转移到快照那个地方,image本身归0,后写入的会计算进去
  • 2、如果对做了快照的镜像做sparsify,会在显示上显示镜像使用很大的空间,这个地方通过exact参数来检查真实占用
  • 3、windows自带了trim,注意回收站及时清理,才能释放,自带的trim是文件级别的触发的,对底层友好
  • 4、如果对全盘做trim的操作,那么底层的会用0空间的对象去填充这个image,底层会产生很多空对象
  • 5、sparsify是清理的占0空间的写入,比如zero写入的,可以清理,写入实际文件又删除的情况不是sparsify去处理的,是trim处理的

再精简总结就是:

  • 1、查询真实用量就加上exact参数
  • 2、不要做sparsify操作和windows的全盘trim,让系统的trim自己处理