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 如何理解?
为什么先写元数据,数据没有落盘,根本不知道数据具体位置呀
延迟写入 (Deferred Write)
BlueStore 用于优化小的、未对齐 I/O(尤其随机写)的机制。
直接写入很小的(如 4KB)、未对齐的 I/O 效率极低,会引发读-修改-写放大:
•
需先读取整个对齐块
•
在内存修改其中一部分
•
再整个写回磁盘 额外增加 I/O 操作和延迟。
✅ 解决方案 采用 积少成多,批量处理 策略:
1
延迟 小 I/O 请求到达时,不立即写入磁盘。
2
缓冲 数据被放入专用的内存缓冲区。
3
批量处理 等待以下时机,再将缓冲区内多个小 I/O 批量、对齐地写入磁盘:
•
缓冲区已满
•
积压 I/O 数量达到阈值
•
出现更大的、对齐的 I/O 可合并
•
需同步落盘时 (如 fsync
)
核心答案: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
•
数据没有写入磁盘前 都可能丢失数据,因此必须采取办法解决
•
元数据写写入时候,预先确定了数据位置。