PG 存储调用与数据读取机制分析
1. 概述
PG(Placement Group)是 Ceph OSD 中管理对象存储的核心组件。PG 通过 ObjectStore 接口与底层存储后端(如 BlueStore、FileStore)交互,实现对象的读写、元数据管理等功能。
1.1 核心组件
- ObjectStore:存储后端抽象接口
- CollectionHandle (ch):集合句柄,用于标识和管理 PG 的存储集合
- PGTransaction:PG 层的事务抽象
- ObjectStore::Transaction:存储层的事务实现
1.2 存储层次
1 | PG (PrimaryLogPG) |
2. 存储初始化与集合管理
2.1 PG 存储初始化
PG 在创建时会初始化存储相关的组件:
1 | // PG 构造函数 |
关键成员变量:
coll:集合 ID(coll_t),标识 PG 的存储集合ch:集合句柄(ObjectStore::CollectionHandle),用于访问集合
2.2 打开集合(Collection)
PG 在加载时会打开对应的存储集合:
1 | // OSD::load_pgs() 中 |
集合句柄的作用:
- 标识 PG 的存储集合
- 用于事务提交和查询操作
- 保证事务在同一个集合内按顺序执行
2.3 集合与 PG 的对应关系
1 | // PG ID 到集合 ID 的转换 |
3. 存储读取机制
3.1 读取 PG 元数据
PG 启动时需要从存储中读取元数据:
1 | // PG::read_state() - 读取 PG 状态 |
读取 PG 信息:
1 | int PG::read_info(ObjectStore *store, spg_t pgid, const coll_t &coll, |
3.2 读取对象数据
3.2.1 通过 PGBackend 读取
PG 通过 PGBackend 读取对象数据:
1 | // PrimaryLogPG::do_op() - 处理客户端操作 |
3.2.2 读取操作流程
1 | // PrimaryLogPG::execute_ctx() - 执行操作上下文 |
3.2.3 直接存储读取
在某些场景下,PG 会直接调用存储接口读取数据:
1 | // 读取对象属性 |
3.3 异步读取
对于 EC(纠删码)池,支持异步读取:
1 | // PrimaryLogPG::OpContext::start_async_reads() |
4. 存储写入机制
4.1 事务构建
PG 通过事务(Transaction)来组织写入操作:
1 | // PrimaryLogPG::execute_ctx() - 构建事务 |
4.2 事务提交流程
1 | // PrimaryLogPG::execute_ctx() - 提交事务 |
4.3 通过 PGBackend 写入
PG 通过 PGBackend 处理写入操作:
1 | // ReplicatedBackend::submit_transaction() |
4.4 直接存储写入
在某些场景下,PG 会直接写入存储:
1 | // 写入 PG 状态 |
5. 存储接口详解
5.1 ObjectStore 核心接口
5.1.1 集合操作
1 | // 打开集合 |
5.1.2 对象读取
1 | // 读取对象数据 |
5.1.3 OMAP 操作
1 | // 读取 OMAP 值 |
5.1.4 事务操作
1 | // 提交事务 |
5.2 Transaction 操作类型
存储事务支持多种操作:
1 | // 写入数据 |
6. 数据读取场景
6.1 客户端读取操作
1 | // PrimaryLogPG::do_op() - 处理读取操作 |
6.2 恢复读取
1 | // ReplicatedBackend::recover_object() - 恢复对象 |
6.3 Scrub 读取
1 | // 在 Scrub 过程中读取对象 |
7. 数据写入场景
7.1 客户端写入操作
1 | // PrimaryLogPG::execute_ctx() - 执行写入 |
7.2 PG 状态写入
1 | // PeeringState::write_if_dirty() - 写入 PG 状态 |
7.3 恢复写入
1 | // ReplicatedBackend::run_recovery_op() - 执行恢复操作 |
8. 存储调用路径
8.1 读取路径
1 | 客户端请求 |
8.2 写入路径
1 | 客户端请求 |
9. 关键数据结构
9.1 CollectionHandle
1 | // 集合句柄 |
9.2 PGTransaction
1 | // PG 层事务抽象 |
9.3 ObjectStore::Transaction
1 | // 存储层事务 |
10. 性能优化
10.1 对象上下文缓存
1 | // ObjectContext 缓存对象信息 |
10.2 批量操作
1 | // 批量提交事务 |
10.3 异步操作
1 | // 异步读取(EC 池) |
11. 错误处理
11.1 读取错误
1 | // 读取失败处理 |
11.2 写入错误
1 | // 事务提交失败处理 |
12. 总结
12.1 核心机制
- 集合管理:每个 PG 对应一个存储集合,通过
CollectionHandle访问 - 事务机制:通过
PGTransaction和ObjectStore::Transaction组织操作 - 读写分离:读取可以直接调用存储接口,写入通过事务提交
- 后端抽象:通过
PGBackend抽象复制/EC 差异
12.2 关键接口
- 集合操作:
open_collection(),flush(),flush_commit() - 读取操作:
read(),getattr(),stat(),omap_get_values() - 写入操作:通过
Transaction的write(),setattr(),omap_setkeys()等 - 事务提交:
queue_transaction()
12.3 调用流程
- 初始化:PG 创建时初始化
coll,加载时打开ch - 读取:通过
ch和store接口直接读取 - 写入:构建
PGTransaction,转换为ObjectStore::Transaction,通过PGBackend提交 - 提交:
store->queue_transaction(ch, t)提交到底层存储
12.4 相关文件
PG.h/cc:PG 基础类,管理集合和存储访问PrimaryLogPG.h/cc:主日志 PG 实现,处理客户端操作PGBackend.h:后端抽象接口ReplicatedBackend.h/cc:复制后端实现ECBackend.h/cc:EC 后端实现ObjectStore.h:存储后端接口定义os/Transaction.h:事务定义
正在加载留言…