进击云原生

V2

2022/08/29阅读:18主题:山吹

Ceph 存储的那点事儿 — Trim/Discard

Ceph 存储的那点事儿 — Trim/Discard

作者:ProdanLabs
出处:https://www.modb.pro/db/137720

在 Linux 中, Ceph rados 块设备映像( RBD image ) 通过内核中的 rbd 模块和 rbd 存储驱动向 Linux 内核注册自身并向内核提供文件操作的类,使快设备也像文件一样使用。

当我们在操作系统中删除一个文件时,并不会在块设备上擦除,而是把文件在元数据结构中占用的 LBA 地址标记为未使用。

Ceph RBD

Ceph RBD image 是稀疏格式 (sparse file),在 Ceph 存储的数据都会被切分成 object,使用的 Block 随着用户写入数据的增加而增加。当用户删除文件后,这些 obejct 对应的 Block 不再使用,但也没有被释放。对于 Ceph 来说它并不知道文件系统做的操作,会认为  Block 仍在使用。

验证

// 创建 rbd image
# rbd create volume01 --size 100G -p rbd

// 映射的块设备
# rbd map --image rbd/volume01
/dev/rbd0

// 格式化
# mkfs.ext4 /dev/rbd0

// 不加参数挂载文件系统
# mount /dev/rbd0 /mnt/data

写入测试数据之前的 osd 空间(6.3G)

# ceph osd df
ID  CLASS  WEIGHT   REWEIGHT  SIZE     RAW USE  DATA     OMAP     META      AVAIL    %USE  VAR   PGS  STATUS
 2    hdd  0.04880   1.00000   50 GiB  2.1 GiB  1.1 GiB  1.8 MiB  1022 MiB   48 GiB  4.20  1.00   33      up
 1    hdd  0.04880   1.00000   50 GiB  2.1 GiB  1.1 GiB  1.7 MiB  1022 MiB   48 GiB  4.20  1.00   33      up
 0    hdd  0.04880   1.00000   50 GiB  2.1 GiB  1.1 GiB  1.8 MiB  1022 MiB   48 GiB  4.20  1.00   33      up
                       TOTAL  150 GiB  6.3 GiB  3.3 GiB  5.3 MiB   3.0 GiB  144 GiB  4.20    

写入 5G 测试数据

# cd /mnt/data/
# dd if=/dev/zero of=test bs=10M count=512
512+0 records in
512+0 records out
5368709120 bytes (5.4 GB, 5.0 GiB) copied, 120.843 s, 44.4 MB/s
# du -sh /mnt/data/*
16K     /mnt/data/lost+found
5.1G    /mnt/data/test

写入测试数据之后的 osd 空间(21G)

REWEIGHT  SIZE     RAW USE  DATA     OMAP     META      AVAIL    %USE   VAR   PGS  STATUS
 2    hdd  0.04880   1.00000   50 GiB  7.1 GiB  6.1 GiB  1.8 MiB  1022 MiB   43 GiB  14.20  1.00   33      up
 1    hdd  0.04880   1.00000   50 GiB  7.1 GiB  6.1 GiB  1.7 MiB  1022 MiB   43 GiB  14.20  1.00   33      up
 0    hdd  0.04880   1.00000   50 GiB  7.1 GiB  6.1 GiB  1.8 MiB  1022 MiB   43 GiB  14.20  1.00   33      up
                       TOTAL  150 GiB   21 GiB   18 GiB  5.3 MiB   3.0 GiB  129 GiB  14.20
MIN/MAX VAR: 1.00/1.00  STDDEV: 0

删除测试数据后,osd 空间仍然是 21G

# rm -f test
# du -sh /mnt/data/*
16K     /mnt/data/lost+found
# ceph osd df
ID  CLASS  WEIGHT   REWEIGHT  SIZE     RAW USE  DATA     OMAP     META      AVAIL    %USE   VAR   PGS  STATUS
 2    hdd  0.04880   1.00000   50 GiB  7.1 GiB  6.1 GiB  1.8 MiB  1022 MiB   43 GiB  14.20  1.00   33      up
 1    hdd  0.04880   1.00000   50 GiB  7.1 GiB  6.1 GiB  1.7 MiB  1022 MiB   43 GiB  14.20  1.00   33      up
 0    hdd  0.04880   1.00000   50 GiB  7.1 GiB  6.1 GiB  1.8 MiB  1022 MiB   43 GiB  14.20  1.00   33      up
                       TOTAL  150 GiB   21 GiB   18 GiB  5.3 MiB   3.0 GiB  129 GiB  14.20
MIN/MAX VAR: 1.00/1.00  STDDEV: 0

Linux 提供了一种 Trim/Discard 回收机制,文件系统可以通知块设备释放掉未使用的 Block 。

Trim

fstrim 用于回收(Trim)一个已挂载的文件系统上所有未使用的 Block , 发送此指令给 Block controller , 以告诉它哪些数据对应的 LBA 地址是无效的,然后进行 GC 。

# fstrim -v  /mnt/data
/mnt/data: 5.2 GiB (5628641280 bytes) trimmed

osd 空间变成了 6.3G

# ceph osd df
ID  CLASS  WEIGHT   REWEIGHT  SIZE     RAW USE  DATA     OMAP     META      AVAIL    %USE  VAR   PGS  STATUS
 2    hdd  0.04880   1.00000   50 GiB  2.1 GiB  1.1 GiB  1.8 MiB  1022 MiB   48 GiB  4.20  1.00   33      up
 1    hdd  0.04880   1.00000   50 GiB  2.1 GiB  1.1 GiB  1.7 MiB  1022 MiB   48 GiB  4.20  1.00   33      up
 0    hdd  0.04880   1.00000   50 GiB  2.1 GiB  1.1 GiB  1.8 MiB  1022 MiB   48 GiB  4.20  1.00   33      up
                       TOTAL  150 GiB  6.3 GiB  3.3 GiB  5.3 MiB   3.0 GiB  144 GiB  4.20
MIN/MAX VAR: 1.00/1.00  STDDEV: 0

Discard

discard 是 mount 命令的参数,在挂载文件系统时指定 discard 参数后,文件系统中删除文件后会自动触发 Trim/Discard 操作,通知块设备释放掉未使用的 Block 。

加  discard 参数挂载

# mount -o discard /dev/rbd0 /mnt/data/

测试

// osd 空间 6.3 GiB
# ceph osd df
ID  CLASS  WEIGHT   REWEIGHT  SIZE     RAW USE  DATA     OMAP     META      AVAIL    %USE  VAR   PGS  STATUS
 2    hdd  0.04880   1.00000   50 GiB  2.1 GiB  1.1 GiB  1.8 MiB  1022 MiB   48 GiB  4.20  1.00   33      up
 1    hdd  0.04880   1.00000   50 GiB  2.1 GiB  1.1 GiB  1.7 MiB  1022 MiB   48 GiB  4.20  1.00   33      up
 0    hdd  0.04880   1.00000   50 GiB  2.1 GiB  1.1 GiB  1.8 MiB  1022 MiB   48 GiB  4.20  1.00   33      up
                       TOTAL  150 GiB  6.3 GiB  3.3 GiB  5.3 MiB   3.0 GiB  144 GiB  4.20
MIN/MAX VAR: 1.00/1.00  STDDEV: 0

// 写入数据
# cd /mnt/data
# dd if=/dev/zero of=test bs=10M count=100

// osd 空间 9.2 GiB
# ceph osd df
ID  CLASS  WEIGHT   REWEIGHT  SIZE     RAW USE  DATA     OMAP     META      AVAIL    %USE  VAR   PGS  STATUS
 2    hdd  0.04880   1.00000   50 GiB  3.1 GiB  2.1 GiB  1.8 MiB  1022 MiB   47 GiB  6.15  1.00   33      up
 1    hdd  0.04880   1.00000   50 GiB  3.1 GiB  2.1 GiB  1.7 MiB  1022 MiB   47 GiB  6.15  1.00   33      up
 0    hdd  0.04880   1.00000   50 GiB  3.1 GiB  2.1 GiB  1.8 MiB  1022 MiB   47 GiB  6.15  1.00   33      up
                       TOTAL  150 GiB  9.2 GiB  6.2 GiB  5.3 MiB   3.0 GiB  141 GiB  6.15
MIN/MAX VAR: 1.00/1.00  STDDEV: 0

// 删除数据
# rm -f test

// osd 空间 6.3 GiB
# ceph osd df
ID  CLASS  WEIGHT   REWEIGHT  SIZE     RAW USE  DATA     OMAP     META      AVAIL    %USE  VAR   PGS  STATUS
 2    hdd  0.04880   1.00000   50 GiB  2.1 GiB  1.1 GiB  1.8 MiB  1022 MiB   48 GiB  4.20  1.00   33      up
 1    hdd  0.04880   1.00000   50 GiB  2.1 GiB  1.1 GiB  1.7 MiB  1022 MiB   48 GiB  4.20  1.00   33      up
 0    hdd  0.04880   1.00000   50 GiB  2.1 GiB  1.1 GiB  1.8 MiB  1022 MiB   48 GiB  4.20  1.00   33      up
                       TOTAL  150 GiB  6.3 GiB  3.3 GiB  5.3 MiB   3.0 GiB  144 GiB  4.20
MIN/MAX VAR: 1.00/1.00  STDDEV: 0

Kubernetes 支持挂载选项,在  StorageClass 对象声明即可。

mountOptions:
  - discard

PersistentVolume 对象可以通过下面的注解声明,但是未来会弃用。

metadata:
  annotations:
  volume.beta.kubernetes.io/mount-options: "discard"

可以使用 findmnt 或 mount 命令查看有没有 discard 参数。

# findmnt -lo source,target,fstype,label,options,used | grep pvc-5d7888a2-39e4-46a1-a18b-e8244e8f0b3c
/dev/rbd0                                                                                                                                                                  /var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc-5d7888a2-39e4-46a1-a18b-e8244e8f0b3c/globalmount/0001-0024-bd241c5a-d012-11eb-8215-e977530c8b31-0000000000000003-6b238965-d3f9-11eb-9891-56a6d268783b         rw,relatime,discard,stripe=16  2.5M
/dev/rbd0                                                                                                                                                                  /var/lib/kubelet/pods/88020e6c-5e4c-4a70-a7bc-23f507706947/volumes/kubernetes.io~csi/pvc-5d7888a2-39e4-46a1-a18b-e8244e8f0b3c/mount                                                                             rw,relatime,discard,stripe=16  2.5M

# mount -l  | grep "/dev/rbd0"
/dev/rbd0 on /mnt/data type ext4 (rw,relatime,discard,stripe=16)

总结

实际上做不做 Trim/Discard 操作对于 HDD 类型的文件系统来说没什么影响, HDD  可以覆盖使用,但是 SSD  不允许覆盖,只能在系统要求在相同的地方写入数据时先擦除再写入,这会影响 SSD 的性能,因此建议 SSD 做 Trim/Discard 操作。

对于 Ceph 来说,不做 Trim/Discard 操作在  OSD 看到的使用空间跟实际使用的空间会不一样。这就有点像 Oracle 的高水位线了,delete 表数据,表空间的高水位线不会下降,但是可以覆盖。

如果没有做  Trim/Discard 操作后再删掉 RBD image ,Ceph OSD 会以异步方式删除数据,因此不能立即释放磁盘空间,可以通过查看 pg 的状态查看进度。

# ceph pg stat
33 pgs: 10 active+clean, 19 active+clean+snaptrim_wait, 4 active+clean+snaptrim; 1.5 GiB data, 4.8 GiB used, 142 GiB / 150 GiB avail
# ceph pg stat
33 pgs: 10 active+clean, 19 active+clean+snaptrim_wait, 4 active+clean+snaptrim; 1.2 GiB data, 3.8 GiB used, 143 GiB / 150 GiB avail
# ceph pg stat
33 pgs: 10 active+clean, 19 active+clean+snaptrim_wait, 4 active+clean+snaptrim; 1.1 GiB data, 3.5 GiB used, 144 GiB / 150 GiB avail
# ceph pg stat
33 pgs: 10 active+clean, 19 active+clean+snaptrim_wait, 4 active+clean+snaptrim; 1.1 GiB data, 3.5 GiB used, 144 GiB / 150 GiB avail
# ceph pg stat
33 pgs: 10 active+clean, 19 active+clean+snaptrim_wait, 4 active+clean+snaptrim; 1.1 GiB data, 3.5 GiB used, 144 GiB / 150 GiB avail
# ceph pg stat
33 pgs: 19 active+clean, 10 active+clean+snaptrim_wait, 4 active+clean+snaptrim; 812 MiB data, 2.6 GiB used, 144 GiB / 150 GiB avail
# ceph pg stat
33 pgs: 33 active+clean; 9.7 MiB data, 229 MiB used, 147 GiB / 150 GiB avail

snaptrim_Wait:Trim 操作等待被调度执行

snaptrim:正在做 Trim 操作

分类:

后端

标签:

运维部署

作者介绍

进击云原生
V2

公众号:进击云原生