首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[答疑]BlueStore 延迟写:先写元数据,数据位置还不确定怎么办?

[答疑]BlueStore 延迟写:先写元数据,数据位置还不确定怎么办?

作者头像
早起的鸟儿有虫吃
发布2025-10-10 13:12:53
发布2025-10-10 13:12:53
150
举报

1. 用户提问:

Ceph 采取统一存储架构,

类型

接口

存储形式

用途

对象存储

RGW (S3/Swift)

对象 (Object)

云原生应用、大数据、备份归档

块存储

RBD

块设备 (Block Device)

虚拟机硬盘、数据库存储

文件系统

CephFS

文件 (File)

传统文件共享、主目录、HPC

将对象存储,块存储,和文件系统存储存储到RADOS , 一个RADOS 对象默认4M

4MB逻辑上的分配单元) 如何存储到 4K (磁盘写入粒度,扇区大小

对用户来说:不需要关心对象数据具体被存储在哪个物理块上

由于 BlueStore 绕过了系统的本地文件系统并直接接管磁盘

就需要设计一个用于组织磁盘数据(例如将对象中的一段逻辑数据映射到物理磁盘等)的数据结构

在 Ceph 的元数据里,有一个叫 onode(object node)的结构。

用命令onode查询如下:

请问:

对象元数据 存储数据具体存储位置

BlueStore

针对小文件的延迟 BlueStore Deferred Write 如何理解?

为什么先写元数据,数据没有落盘,根本不知道数据具体位置呀

2. 回答

针对小文件的延迟写入 (Deferred Write) 如何理解?

延迟写入 (Deferred Write)

BlueStore 用于优化小的、未对齐 I/O(尤其随机写)的机制。

问题 读-修改-写放大

直接写入很小的(如 4KB)、未对齐的 I/O 效率极低,会引发读-修改-写放大

需先读取整个对齐块

在内存修改其中一部分

再整个写回磁盘 额外增加 I/O 操作和延迟。

✅ 解决方案 采用 积少成多,批量处理 策略:

1

延迟 小 I/O 请求到达时,不立即写入磁盘。

2

缓冲 数据被放入专用的内存缓冲区

3

批量处理 等待以下时机,再将缓冲区内多个小 I/O 批量、对齐地写入磁盘:

缓冲区已满

积压 I/O 数量达到阈值

出现更大的、对齐的 I/O 可合并

需同步落盘时 (如 fsync)

3. 为什么先写元数据?数据没落盘,不知道位置呀?

核心答案:BlueStore 采用的是“写时分配” (Copy-on-Write / Allocate-on-Write) 机制。它先“预定”位置并记录在元数据中,然后再写入数据。

这个过程更像“先划车位,再停车”,而不是“停好车再记录位置”。以下是详细步骤:

1

准备阶段 (Preflight) - “规划车位”

当写入请求到来时,BlueStore 首先知道要写入数据的逻辑参数:对象 OID、逻辑偏移 (offset)、数据长度 (length)。

不需要知道数据具体的物理位置就可以开始一个 RocksDB 事务。

2

分配空间 (Allocate) - “划定车位”

BlueStore 的核心组件 Allocator(分配器) 会从空闲空间位图中,为这批数据预先分配一块大小合适的、对齐的物理空间(例如,多个连续的 4KB 块)。此时,物理偏移 (disk_offset) 就已经确定了!

Allocator 就像是停车场管理员,他有一张地图,知道哪些车位是空的。你告诉他需要几个车位,他立刻就能在地图上给你划出来,并标记为“已预定”。

3

写入元数据 (Write Metadata) - “记录车位号”

现在,BlueStore 知道了所有必要信息:逻辑偏移 (offset) -> 新的物理偏移 (disk_offset) -> 数据长度 (length)。

它在一个 RocksDB 事务中,更新对象的元数据 (Onode),将这条新的映射关系 (Extent Map) 持久化到 RocksDB 中。

这一步是至关重要的。它保证了即使系统在接下来的数据写入步骤前崩溃,恢复后也能知道“逻辑地址 A 的数据应该在物理位置 B”,尽管位置 B 里的数据可能是旧的或者是垃圾。这种一致性状态是可以通过事务来管理的。

4

写入数据 (Write Data) - “停车入位”

元数据事务提交后,BlueStore 才真正地将用户数据写入到第 2 步中分配的物理偏移上。

对于延迟写入,数据可能先进入缓冲区,但最终的目标位置早已确定。

5

最终一致性 (最终可选)

总结对比

传统方式 (FileStore)

BlueStore 方式 (智能)

先写数据,后记位置

先分配和记录位置,后写数据

停车时随便找空位,停好后记下号码。

管理员先给你指定一个好车位并记下,你再开过去停。

容易造成碎片化,效率低下。

分配器可以优化空间分配,减少碎片,并且整个过程是事务性的,保证一致性。

疑问:如果故障,这个小文件数据不是丢失了吗?

1

小对象内联(Small Object Inlining)

对于非常小的对象(通常 < 4KB,可配置),BlueStore 会将数据直接内联到 RocksDB 的 value 中

这种情况下,小文件数据确实会进入 RocksDB 的 WAL → memtable → SST 路径

但这是有意的设计选择,不是"误放"

[osd] bluestore_min_alloc_size = 4096

总结

数据没有写入磁盘前 都可能丢失数据,因此必须采取办法解决

元数据写写入时候,预先确定了数据位置。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-09-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端开发成长指南 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 用户提问:
  • 2. 回答
    • 针对小文件的延迟写入 (Deferred Write) 如何理解?
      • 问题 读-修改-写放大
      • 3. 为什么先写元数据?数据没落盘,不知道位置呀?
      • 总结对比
      • 疑问:如果故障,这个小文件数据不是丢失了吗?
    • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档