第2章
Ceph通用模块
本章介绍Ceph源代码通用库中的一些比较关键而又比较复杂的数据结构。Object和Buffer相关的数据结构是普遍使用的。线程池ThreadPool可以提高消息处理的并发能力。Finisher提供了异步操作时来执行回调函数。Throttle在系统的各个模块各个环节都可以看到,它用来限制系统的请求,避免瞬时大量突发请求对系统的冲击。SafteTimer提供了定时器,为超时和定时任务等提供了相应的机制。理解这些数据结构,能够更好理解后面章节的相关内容。
2.1 Object
对象Object是默认为4MB大小的数据块。一个对象就对应本地文件系统中的一个文件。在代码实现中,有object、sobject、hobject、ghobject等不同的类。
结构object_t对应本地文件系统的一个文件,name就是对象名:
`struct object_t {
string name;
......
}`
sobject_t在object_t之上增加了snapshot信息,用于标识是否是快照对象。数据成员snap为快照对象的对应的快照序号。如果一个对象不是快照对象(也就是head对象),那么snap字段就被设置为CEPH_NOSNAP值。
`struct sobject_t {
object_t oid;
snapid_t snap;
......
}`
hobject_t是名字应该是hash object的缩写。
struct hobject_t {
object_t oid;
snapid_t snap;
private:
uint32_t hash;
bool max;
uint32_t nibblewise_key_cache;
uint32_t hash_reverse_bits;
……
public:
int64_t pool;
string nspace;
private:
string key;
......
}
其在sobject_t的基础上增加了一些字段:
int64_t pool:所在的pool的id。
string nspace:nspace一般为空,它用于标识特殊的对象。
string key:对象的特殊标记。
string hash:hash和key不能同时设置,hash值一般设置为就是pg的id值。
ghobject_t在对象hobject_t的基础上,添加了generation字段和shard_id字段,这个用于ErasureCode 模式下的PG:
shard_id用于标识对象所在的osd在EC类型的PG中的序号,对应EC来说,每个osd在PG中的序号在数据恢复时非常关键。如果是Replicate类型的PG,那么字段就设置为NO_SHARD(-1),该字段对于replicate是没用。
generation用于记录对象的版本号。当PG为EC时,写操作需要区分写前后两个版本的object,写操作保存对象的上一个版本(generation)的对象,当EC写失败时,可以rollback到上一个版本。
struct ghobject_t {
hobject_t hobj;
gen_t generation;
shard_id_t shard_id;
bool max;
public:
static const gen_t NO_GEN = UINT64_MAX;
......
}