一、BlueStore 定位与日志优化
BlueStore 可理解为一个事务型本地日志文件系统(但实际上存储的是对象),面向全闪存阵列设计。在保证数据可靠性与一致性的前提下,它通过优化日志机制,尽可能降低 "双写" 问题对写性能的影响。
1. 日志设备选型的变化
- 传统方案:机械盘存数据、SSD 当日志盘,瓶颈在寻址时间,日志盘的时延优势明显。
- 全闪存方案:数据盘与日志盘均为高速 NVMe SSD,瓶颈从寻址时间变为数据传输时间。当日志写入数据量超过一定规模时,写日志的时延优势大幅减弱,日志存在的必要性随之降低。
2. 增量日志优化方案
针对大范围覆盖写,可采用增量日志:
- 仅对前后非磁盘块对齐的部分写日志;
- 其他不需要执行 RMW 的部分直接重定向写,以此减少日志写入量。
二、写入核心策略:RMW 与 COW
1. RMW(Read-Modify-Write)
指覆盖写内容不足一个磁盘块大小时,需先读取原块、合并新数据、再写回。
- 主要问题:
- 引入额外的读惩罚;
- 中途掉电会导致潜在的数据损坏风险。
2. COW(Copy-On-Write)
指覆盖写时不直接修改原位置,而是写入新块,更新指针后再释放原空间。
- 理论优势:解决 RMW 的问题;
- 固有缺陷:
- 破坏数据物理连续性,后续读操作需多次 I/O 并合并数据,影响读性能;
- 引入更多元数据,增加系统开销;
- 在 SSD 上,COW 也能将随机写转化为顺序写,对写性能有一定补偿。
3. BlueStore 的混合写入策略
BlueStore 综合运用 RMW 和 COW 策略:
- 首尾非块对齐部分:采用 RMW + 日志;
- 中间块对齐部分:采用 COW;
- 为解决 COW 掉电风险,操作需先写入日志盘,再更新数据盘。
三、事务模型与 ACID 语义
1. 事务提交方式
所有写请求通过 queue_transactions 接口提交,多个请求组成事务组,作为整体需满足 ACID 语义。
- 受限于 PG 实现,当前一个事务组不能真正对同一个 PG 下的多个对象执行原子操作。
2. 关键上下文信息
操作 PG 下的对象,需先获取 BlueStore 中的两类核心上下文:
- PG 上下文:保存 PG 相关的关键元数据;
- 对象上下文:保存对象相关的关键元数据;
- 这两类上下文均通过
kvDB(RocksDB)固化到磁盘,因此需要稳定的磁盘数据结构以保证兼容性。
四、写请求的生命周期与队列管理
BlueStore 为每个 PG 设计了 OpSequencer 队列,按阶段管理写请求:
- 日志阶段:写请求创建后,先写入日志;
- 覆盖写阶段:日志写入完成后,再写入数据盘。
- 为了保证顺序执行,需额外队列将进入覆盖写阶段的带日志请求再次排序。