ceph中的rbd的稀疏写入

复制代码
[root@node2 ~]# rbd du --pool rbdpool myimage --user1
rbd: unrecognised option '--user1'
[root@node2 ~]# rbd du --pool rbdpool myimage --id user1
NAME     PROVISIONED  USED
myimage        1 GiB  28 MiB
[root@node2 ~]# dd if=/dev/zero of=/mnt/ceph-data/test_100mb.dat bs=1M count=700
700+0 records in
700+0 records out
734003200 bytes (734 MB, 700 MiB) copied, 7.48139 s, 98.1 MB/s
[root@node2 ~]# df -h | grep ceph
/dev/rbd0               974M  701M  207M  78% /mnt/ceph-data
[root@node2 ~]# rbd du --pool rbdpool myimage --id user1
NAME     PROVISIONED  USED
myimage        1 GiB  516 MiB
[root@node2 ~]# rbd du --pool rbdpool myimage --id user1
NAME     PROVISIONED  USED
myimage        1 GiB  728 MiB
[root@node2 ~]# rbd du --pool rbdpool myimage --id user1
NAME     PROVISIONED  USED
myimage        1 GiB  728 MiB
[root@node2 ~]# rm -f /mnt/ceph-data/test_100mb.dat
[root@node2 ~]# rbd du --pool rbdpool myimage --id user1
NAME     PROVISIONED  USED
myimage        1 GiB  728 MiB
[root@node2 ~]# df -h | grep ceph
/dev/rbd0               974M   24K  907M   1% /mnt/ceph-data
[root@node2 ~]# dd if=/dev/zero of=/mnt/ceph-data/test222_100mb.dat bs=1M count=700
700+0 records in
700+0 records out
734003200 bytes (734 MB, 700 MiB) copied, 4.85672 s, 151 MB/s
[root@node2 ~]# df -h | grep ceph
/dev/rbd0               974M  701M  207M  78% /mnt/ceph-data
[root@node2 ~]# df -h | grep ceph
/dev/rbd0               974M  701M  207M  78% /mnt/ceph-data
[root@node2 ~]# rbd du --pool rbdpool myimage --id user1
NAME     PROVISIONED  USED
myimage        1 GiB  860 MiB
[root@node2 ~]# ceph df detail
2025-12-19T11:19:28.380+0800 7f3f3908b640 -1 auth: unable to find a keyring on /etc/ceph/ceph.client.admin.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bin,: (2) No such file or directory
2025-12-19T11:19:28.380+0800 7f3f3908b640 -1 AuthRegistry(0x7f3f3405eaa0) no keyring found at /etc/ceph/ceph.client.admin.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bin,, disabling cephx
2025-12-19T11:19:28.381+0800 7f3f3908b640 -1 auth: unable to find a keyring on /etc/ceph/ceph.client.admin.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bin,: (2) No such file or directory
2025-12-19T11:19:28.381+0800 7f3f3908b640 -1 AuthRegistry(0x7f3f3908a0d0) no keyring found at /etc/ceph/ceph.client.admin.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bin,, disabling cephx
2025-12-19T11:19:28.381+0800 7f3f32d9d640 -1 monclient(hunting): handle_auth_bad_method server allowed_methods [2] but i only support [1]
2025-12-19T11:19:28.382+0800 7f3f3259c640 -1 monclient(hunting): handle_auth_bad_method server allowed_methods [2] but i only support [1]
2025-12-19T11:19:28.382+0800 7f3f3359e640 -1 monclient(hunting): handle_auth_bad_method server allowed_methods [2] but i only support [1]
2025-12-19T11:19:28.382+0800 7f3f3908b640 -1 monclient: authenticate NOTE: no keyring found; disabled cephx authentication
[errno 13] RADOS permission denied (error connecting to the cluster)
[root@node2 ~]# ceph df detail --id user1
--- RAW STORAGE ---
CLASS     SIZE    AVAIL     USED  RAW USED  %RAW USED
hdd    600 GiB  582 GiB   18 GiB    18 GiB       2.93
ssd    300 GiB  298 GiB  1.6 GiB   1.6 GiB       0.55
TOTAL  900 GiB  881 GiB   19 GiB    19 GiB       2.14

--- POOLS ---
POOL                   ID  PGS   STORED   (DATA)  (OMAP)  OBJECTS     USED   (DATA)  (OMAP)  %USED  MAX AVAIL  QUOTA OBJECTS  QUOTA BYTES  DIRTY  USED COMPR  UNDER COMPR
device_health_metrics   1    1      0 B      0 B     0 B        0      0 B      0 B     0 B      0    277 GiB            N/A          N/A    N/A         0 B          0 B
testpool                5   64  5.2 GiB  5.2 GiB     0 B    1.37k   15 GiB   15 GiB     0 B   2.68    184 GiB            N/A          N/A    N/A         0 B          0 B
rbdpool                 6   64  833 MiB  833 MiB     0 B      221  2.4 GiB  2.4 GiB     0 B   0.29    277 GiB            N/A          N/A    N/A         0 B          0 B
[root@node2 ~]# rbd du --pool rbdpool myimage --id user1
NAME     PROVISIONED  USED
myimage        1 GiB  860 MiB
[root@node2 ~]# rm -f /mnt/ceph-data/test222_100mb.dat
[root@node2 ~]# dd if=/dev/zero of=/mnt/ceph-data/test333_100mb.dat bs=1M count=700
700+0 records in
700+0 records out
734003200 bytes (734 MB, 700 MiB) copied, 4.84126 s, 152 MB/s
[root@node2 ~]# rbd du --pool rbdpool myimage --id user1
NAME     PROVISIONED  USED
myimage        1 GiB  860 MiB
[root@node2 ~]# ceph df detail --id user1
--- RAW STORAGE ---
CLASS     SIZE    AVAIL     USED  RAW USED  %RAW USED
hdd    600 GiB  582 GiB   18 GiB    18 GiB       2.93
ssd    300 GiB  298 GiB  1.7 GiB   1.7 GiB       0.55
TOTAL  900 GiB  881 GiB   19 GiB    19 GiB       2.14

--- POOLS ---
POOL                   ID  PGS   STORED   (DATA)  (OMAP)  OBJECTS     USED   (DATA)  (OMAP)  %USED  MAX AVAIL  QUOTA OBJECTS  QUOTA BYTES  DIRTY  USED COMPR  UNDER COMPR
device_health_metrics   1    1      0 B      0 B     0 B        0      0 B      0 B     0 B      0    277 GiB            N/A          N/A    N/A         0 B          0 B
testpool                5   64  5.2 GiB  5.2 GiB     0 B    1.37k   15 GiB   15 GiB     0 B   2.68    184 GiB            N/A          N/A    N/A         0 B          0 B
rbdpool                 6   64  833 MiB  833 MiB     0 B      221  2.4 GiB  2.4 GiB     0 B   0.29    277 GiB            N/A          N/A    N/A         0 B          0 B
[root@node2 ~]# ceph df detail --id user1
--- RAW STORAGE ---
CLASS     SIZE    AVAIL     USED  RAW USED  %RAW USED
hdd    600 GiB  582 GiB   18 GiB    18 GiB       2.94
ssd    300 GiB  298 GiB  1.7 GiB   1.7 GiB       0.55
TOTAL  900 GiB  881 GiB   19 GiB    19 GiB       2.15

--- POOLS ---
POOL                   ID  PGS   STORED   (DATA)  (OMAP)  OBJECTS     USED   (DATA)  (OMAP)  %USED  MAX AVAIL  QUOTA OBJECTS  QUOTA BYTES  DIRTY  USED COMPR  UNDER COMPR
device_health_metrics   1    1      0 B      0 B     0 B        0      0 B      0 B     0 B      0    277 GiB            N/A          N/A    N/A         0 B          0 B
testpool                5   64  5.2 GiB  5.2 GiB     0 B    1.37k   15 GiB   15 GiB     0 B   2.68    184 GiB            N/A          N/A    N/A         0 B          0 B
rbdpool                 6   64  833 MiB  833 MiB     0 B      221  2.4 GiB  2.4 GiB     0 B   0.29    277 GiB            N/A          N/A    N/A         0 B          0 B
[root@node2 ~]# rm -f /mnt/ceph-data/test333_100mb.dat
[root@node2 ~]# dd if=/dev/zero of=/mnt/ceph-data/test444_100mb.dat bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.00916691 s, 1.1 GB/s
[root@node2 ~]# ceph df detail --id user1
--- RAW STORAGE ---
CLASS     SIZE    AVAIL     USED  RAW USED  %RAW USED
hdd    600 GiB  582 GiB   18 GiB    18 GiB       2.93
ssd    300 GiB  298 GiB  1.7 GiB   1.7 GiB       0.55
TOTAL  900 GiB  881 GiB   19 GiB    19 GiB       2.14

--- POOLS ---
POOL                   ID  PGS   STORED   (DATA)  (OMAP)  OBJECTS     USED   (DATA)  (OMAP)  %USED  MAX AVAIL  QUOTA OBJECTS  QUOTA BYTES  DIRTY  USED COMPR  UNDER COMPR
device_health_metrics   1    1      0 B      0 B     0 B        0      0 B      0 B     0 B      0    277 GiB            N/A          N/A    N/A         0 B          0 B
testpool                5   64  5.2 GiB  5.2 GiB     0 B    1.37k   15 GiB   15 GiB     0 B   2.68    184 GiB            N/A          N/A    N/A         0 B          0 B
rbdpool                 6   64  833 MiB  833 MiB     0 B      221  2.4 GiB  2.4 GiB     0 B   0.29    277 GiB            N/A          N/A    N/A         0 B          0 B
[root@node2 ~]# ceph df detail --id user1
--- RAW STORAGE ---
CLASS     SIZE    AVAIL     USED  RAW USED  %RAW USED
hdd    600 GiB  582 GiB   18 GiB    18 GiB       2.93
ssd    300 GiB  298 GiB  1.7 GiB   1.7 GiB       0.55
TOTAL  900 GiB  881 GiB   19 GiB    19 GiB       2.14

--- POOLS ---
POOL                   ID  PGS   STORED   (DATA)  (OMAP)  OBJECTS     USED   (DATA)  (OMAP)  %USED  MAX AVAIL  QUOTA OBJECTS  QUOTA BYTES  DIRTY  USED COMPR  UNDER COMPR
device_health_metrics   1    1      0 B      0 B     0 B        0      0 B      0 B     0 B      0    277 GiB            N/A          N/A    N/A         0 B          0 B
testpool                5   64  5.2 GiB  5.2 GiB     0 B    1.37k   15 GiB   15 GiB     0 B   2.68    184 GiB            N/A          N/A    N/A         0 B          0 B
rbdpool                 6   64  833 MiB  833 MiB     0 B      221  2.4 GiB  2.4 GiB     0 B   0.29    277 GiB            N/A          N/A    N/A         0 B          0 B
[root@node2 ~]# df -h | grep ceph
/dev/rbd0               974M   11M  897M   2% /mnt/ceph-data
[root@node2 ~]# dd if=/dev/zero of=/mnt/ceph-data/test555_100mb.dat bs=1M count=900
900+0 records in
900+0 records out
943718400 bytes (944 MB, 900 MiB) copied, 8.54251 s, 110 MB/s
[root@node2 ~]# ceph df detail --id user1
--- RAW STORAGE ---
CLASS     SIZE    AVAIL     USED  RAW USED  %RAW USED
hdd    600 GiB  582 GiB   18 GiB    18 GiB       2.94
ssd    300 GiB  298 GiB  1.7 GiB   1.7 GiB       0.56
TOTAL  900 GiB  881 GiB   19 GiB    19 GiB       2.14

--- POOLS ---
POOL                   ID  PGS   STORED   (DATA)  (OMAP)  OBJECTS     USED   (DATA)  (OMAP)  %USED  MAX AVAIL  QUOTA OBJECTS  QUOTA BYTES  DIRTY  USED COMPR  UNDER COMPR
device_health_metrics   1    1      0 B      0 B     0 B        0      0 B      0 B     0 B      0    277 GiB            N/A          N/A    N/A         0 B          0 B
testpool                5   64  5.2 GiB  5.2 GiB     0 B    1.37k   15 GiB   15 GiB     0 B   2.68    184 GiB            N/A          N/A    N/A         0 B          0 B
rbdpool                 6   64  860 MiB  860 MiB     0 B      227  2.5 GiB  2.5 GiB     0 B   0.30    277 GiB            N/A          N/A    N/A         0 B          0 B
[root@node2 ~]# ceph df detail --id user1
--- RAW STORAGE ---
CLASS     SIZE    AVAIL     USED  RAW USED  %RAW USED
hdd    600 GiB  582 GiB   18 GiB    18 GiB       2.94
ssd    300 GiB  298 GiB  1.7 GiB   1.7 GiB       0.56
TOTAL  900 GiB  881 GiB   19 GiB    19 GiB       2.14

--- POOLS ---
POOL                   ID  PGS   STORED   (DATA)  (OMAP)  OBJECTS     USED   (DATA)  (OMAP)  %USED  MAX AVAIL  QUOTA OBJECTS  QUOTA BYTES  DIRTY  USED COMPR  UNDER COMPR
device_health_metrics   1    1      0 B      0 B     0 B        0      0 B      0 B     0 B      0    277 GiB            N/A          N/A    N/A         0 B          0 B
testpool                5   64  5.2 GiB  5.2 GiB     0 B    1.37k   15 GiB   15 GiB     0 B   2.68    184 GiB            N/A          N/A    N/A         0 B          0 B
rbdpool                 6   64  860 MiB  860 MiB     0 B      227  2.5 GiB  2.5 GiB     0 B   0.30    277 GiB            N/A          N/A    N/A         0 B          0 B
[root@node2 ~]# df -h | grep ceph
/dev/rbd0               974M  911M     0 100% /mnt/ceph-data
[root@node2 ~]# rbd du --pool rbdpool myimage --id user1
NAME     PROVISIONED  USED
myimage        1 GiB  948 MiB
[root@node2 ~]# ceph df detail --id user1
--- RAW STORAGE ---
CLASS     SIZE    AVAIL     USED  RAW USED  %RAW USED
hdd    600 GiB  582 GiB   18 GiB    18 GiB       2.96
ssd    300 GiB  298 GiB  1.7 GiB   1.7 GiB       0.58
TOTAL  900 GiB  881 GiB   19 GiB    19 GiB       2.16

--- POOLS ---
POOL                   ID  PGS   STORED   (DATA)  (OMAP)  OBJECTS     USED   (DATA)  (OMAP)  %USED  MAX AVAIL  QUOTA OBJECTS  QUOTA BYTES  DIRTY  USED COMPR  UNDER COMPR
device_health_metrics   1    1      0 B      0 B     0 B        0      0 B      0 B     0 B      0    277 GiB            N/A          N/A    N/A         0 B          0 B
testpool                5   64  5.2 GiB  5.2 GiB     0 B    1.37k   15 GiB   15 GiB     0 B   2.68    184 GiB            N/A          N/A    N/A         0 B          0 B
rbdpool                 6   64  917 MiB  917 MiB     0 B      243  2.7 GiB  2.7 GiB     0 B   0.32    277 GiB            N/A          N/A    N/A         0 B          0 B
[root@node2 ~]# ls /mnt
ceph-data
[root@node2 ~]# ls /mnt/ceph-data/
lost+found  test444_100mb.dat  test555_100mb.dat
[root@node2 ~]# rm -f /mnt/ceph-data/test444_100mb.dat
[root@node2 ~]# rm -f /mnt/ceph-data/test555_100mb.dat
[root@node2 ~]# ls /mnt/ceph-data/
lost+found
[root@node2 ~]# ceph df detail --id user1
--- RAW STORAGE ---
CLASS     SIZE    AVAIL     USED  RAW USED  %RAW USED
hdd    600 GiB  582 GiB   18 GiB    18 GiB       2.96
ssd    300 GiB  298 GiB  1.7 GiB   1.7 GiB       0.58
TOTAL  900 GiB  881 GiB   19 GiB    19 GiB       2.16

--- POOLS ---
POOL                   ID  PGS   STORED   (DATA)  (OMAP)  OBJECTS     USED   (DATA)  (OMAP)  %USED  MAX AVAIL  QUOTA OBJECTS  QUOTA BYTES  DIRTY  USED COMPR  UNDER COMPR
device_health_metrics   1    1      0 B      0 B     0 B        0      0 B      0 B     0 B      0    277 GiB            N/A          N/A    N/A         0 B          0 B
testpool                5   64  5.2 GiB  5.2 GiB     0 B    1.37k   15 GiB   15 GiB     0 B   2.68    184 GiB            N/A          N/A    N/A         0 B          0 B
rbdpool                 6   64  917 MiB  917 MiB     0 B      243  2.7 GiB  2.7 GiB     0 B   0.32    277 GiB         

你这个实验现象本身是完全正确的 ,而且它恰好暴露了 RBD + 文件系统 + 稀疏 object + 延迟回收这几层机制叠加后的真实行为。

我给你一个先给结论 → 再逐层拆解 → 最后逐条对照你日志的完整分析。


一、先给结论(非常重要)

你看到的现象不是"Ceph 超额写入"或"越界写入",
而是:

  1. 文件删除 ≠ 底层 object 立刻释放
  2. RBD 是稀疏映像(thin-provisioned)
  3. 新写入会优先复用 image 内已经分配过的 object
  4. 只有当 image 的"逻辑使用"超过 image size,才会真正失败

所以:

"删除文件后空间没立刻回收,但仍能继续写大文件"是 RBD 的正常、必然行为。


二、先澄清一个非常关键的概念(90% 误解来源)

你这里涉及了 三种"空间"

层级 你看到的工具 含义
文件系统空间 df -h /mnt/ceph-data ext4/xfs 视角
RBD image 空间 rbd du myimage image 已分配 object
Ceph pool 空间 ceph df detail pool 实际 object 使用

这三者不会同步变化。


三、逐层解释你看到的"反直觉行为"

1️⃣ 为什么 rmdf 立刻变空?

bash 复制代码
rm test_100mb.dat
df -h

这是文件系统层行为

  • inode 被释放
  • block map 被释放
  • ext4/xfs 认为空间"可用了"

👉 但它只是在 image 里打了"洞(hole)"


2️⃣ 为什么 rbd du 没变?

bash 复制代码
rbd du myimage
USED 728 MiB   (删除前后不变)

这是RBD 层行为

  • object 仍然存在
  • object 内部只是某些 extent 变成 hole
  • object 本身不会因为文件删除而立刻删除

👉 Ceph 不会主动"拆 object"


3️⃣ 那为什么还能继续写一个 700MB 的新文件?

这是最关键的地方 👇

因为:

新写入优先复用 image 内"已经存在的 object 和 stripe_unit"

你的 image:

  • size = 1GiB

  • 已经有 ~728MiB object 被创建过

  • 删除文件只是:

    • 在 object 里打洞
    • 没有释放 object

所以新写:

text 复制代码
700MB

实际上:

  • 大量写入命中了 已有 object 的 hole
  • 没有新 object 被创建
  • image 的"已分配 object 总量"增长很慢甚至不增长

这就是你看到:

bash 复制代码
df -h        → 用了 700M
rbd du       → 从 728M → 860M(小幅上涨)

四、你"看起来像是越界写"的根本原因

你这里有一个非常自然但错误的直觉

"之前删了 700MB,再写 700MB + 700MB ≈ 1.4GB,

image 才 1GB,怎么还能写?"

正确理解是:

image size 限制的是"最大逻辑地址",不是"历史累计写入量"。


举个最直观的比喻(强烈建议记住)

把 RBD image 想成:

一个 1GB 大小的"虚拟硬盘地址空间"

  • 删除文件 ≠ 硬盘缩小

  • 删除文件 ≠ 硬盘被"清零"

  • 只是:

    • 标记哪些块"现在没人用"

你只要:

  • 不写到 1GB 以外的逻辑地址
  • 不新创建超过 image 覆盖范围的 object

👉 就永远不会越界


五、什么时候"真的会写不进去"?

只有一种情况 👇

❌ 真正失败的条件

text 复制代码
写入的文件布局
→ 需要访问 image offset > image_size

也就是:

  • 文件系统认为还有空间
  • 但 RBD image 地址空间已经用完
  • 新的 stripe_unit / object_no 超过 image 边界

这时你会看到:

  • write() 返回 ENOSPC
  • dmesg 里有 rbd I/O error

六、你日志里一个"非常典型"的细节(你可能没注意)

你这里有一段:

bash 复制代码
dd count=900
df -h → 100%
rbd du → 948 MiB

这一步说明:

  • image 的 object 已经非常接近满
  • 新写开始逼近 image 末尾
  • 再继续写就会真正失败

👉 这正好验证了:Ceph 没有超配 image


七、为什么 Ceph 不在 rm 时立刻释放 object?

这是设计选择,不是缺陷:

原因 1:性能

  • 删除文件是高频操作

  • 立刻删除 object 会引发:

    • 大量 PG 更新
    • recovery / rebalance 抖动

原因 2:稀疏对象(hole)

  • object 是稀疏的
  • hole 不占物理空间
  • 删除 extent ≠ 删除 object

原因 3:复用优先

  • 未来写入可以复用 object
  • 减少 object churn

八、那"真正释放空间"要怎么做?

1️⃣ RBD image 层

bash 复制代码
rbd sparsify myimage
  • 会扫描 image
  • 回收全空 object
  • 这是你现在最需要的命令

2️⃣ 文件系统层(ext4)

bash 复制代码
fstrim /mnt/ceph-data
  • 通知下层哪些块是 hole
  • 对 SSD / 稀疏设备非常重要

九、把你这个实验一句话总结(你可以直接写到笔记里)

在 RBD 上删除文件只会在 image 中产生 hole,不会立即释放 object;
后续写入会优先复用这些已存在的 object,因此即使"删除 + 新写"的文件大小之和超过 image size,仍可能成功;
只有当新的写入需要扩展到 image 的逻辑边界之外时,才会真正失败。


十、你这个实验其实"非常成功"

因为它完整验证了

  • striping
  • object 复用
  • 稀疏 image
  • 延迟回收
  • image size 的真实含义
相关推荐
今天_也很困14 小时前
LeetCode热题100-560. 和为 K 的子数组
java·算法·leetcode
在繁华处14 小时前
线程进阶: 无人机自动防空平台开发教程V2
java·无人机
A懿轩A14 小时前
【Java 基础编程】Java 变量与八大基本数据类型详解:从声明到类型转换,零基础也能看懂
java·开发语言·python
m0_7400437314 小时前
【无标题】
java·spring boot·spring·spring cloud·微服务
喵叔哟14 小时前
02-CSharp基础语法快速入门
服务器
Tansmjs14 小时前
使用Python自动收发邮件
jvm·数据库·python
m0_5613596714 小时前
用Python监控系统日志并发送警报
jvm·数据库·python
@ chen15 小时前
Spring事务 核心知识
java·后端·spring
Dxy123931021615 小时前
MySQL INSERT ... ON DUPLICATE KEY UPDATE 与非主键唯一字段
数据库·mysql
aithinker15 小时前
使用QQ邮箱收发邮件遇到的坑 有些WIFI不支持ipv6
java