您的位置:首页 > 移动开发 > Objective-C

CEPH OBJECTSTORE API介绍

2016-04-20 13:35 337 查看
Thomas是本人在Ceph中国社区翻译小组所用的笔名,该文首次发布在Ceph中国社区,现转载到本人博客,以供大家传阅

CEPH OBJECTSTORE API介绍

本文由 Ceph中国社区-Thomas翻译,陈晓熹校稿 。

英文出处:THE CEPH OBJECTSTORE API 欢迎加入 翻译小组

简介

object store是Ceph OSD的一部分,它完成实际的数据存储。当前有三种不同的object store可用:

FileStore: 文件系统+日志后备的存储

KeyValueStore: 基于KV数据库(如:RocksDB, LevelDB)

MemStore: 以内存作为存储(译注:所有数据全部位于内存中的STL::Map或者bufferlist)

(译注:目前还有NewStore,或称BlueStore正在开发)

相关文档

Ceph Performance: Interesting Things Going On

Object Store Architecture Overview

代码

object store源代码位于Ceph源码目录下的os子目录。为方便:ceph github repository。下面的描述基于Ceph commit-ish 6f8b54c from 2015-01-13。

ObjectStore API

抽象类
ObjectStore
是OSD实现存储访问的主要API。



这是一套类文件系统API,但是囊括了将状态转化为事务的操作。存储的是对象,而不是文件。一个对象包含:

字节数据 - 类似于文件系统中的文件内容

扩展属性 - 类似于文件系统中文件的扩展属性。是键值对集合。

omap - 在概念上与扩展属性相似,但有着不同的地址空间大小及访问模式。

一个对象由下述两个id标示:

集合id -
coll_t
cid(一个集合就是一组对象)

对象id -
ghobject_t
oid

操作

下面不是一个完整的列表;只是给你一个印象。注意:有些操作只对事务可用。

事务操作:以事务作为参数

apply_transaction


queue_transactions


常规文件系统操作:

mount


umount


mkfs


mkjournal


statfs


need_journal


sync


flush


snapshot


对象操作:以
coll_t cid
ghobject_t oid
为参数

exists


stat


read


fiemap


getattr


getattrs


集合操作:以
coll_t cid
为参数

collection_getattr


collection_empty


collection_list


list_collections


collection_exists


collections_getattrs


Omap操作:

omap_get


omap_get_header


omap_get_keys


omap_get_values


omap_check_keys


延伸阅读

ObjectStore.h - 注释部分

事务

定义:事务是原始的变更操作序列。类定义ObjectStore::Transaction。支持的操作(摘自ObjectStore.h):

class Transaction {
public:
enum {
OP_NOP =          0,
OP_TOUCH =        9,   // cid, oid
OP_WRITE =        10,  // cid, oid, offset, len, bl
OP_ZERO =         11,  // cid, oid, offset, len
OP_TRUNCATE =     12,  // cid, oid, len
OP_REMOVE =       13,  // cid, oid
OP_SETATTR =      14,  // cid, oid, attrname, bl
OP_SETATTRS =     15,  // cid, oid, attrset
OP_RMATTR =       16,  // cid, oid, attrname
OP_CLONE =        17,  // cid, oid, newoid
OP_CLONERANGE =   18,  // cid, oid, newoid, offset, len
OP_CLONERANGE2 =  30,  // cid, oid, newoid, srcoff, len, dstoff

OP_TRIMCACHE =    19,  // cid, oid, offset, len  **DEPRECATED**

OP_MKCOLL =       20,  // cid
OP_RMCOLL =       21,  // cid
OP_COLL_ADD =     22,  // cid, oldcid, oid
OP_COLL_REMOVE =  23,  // cid, oid
OP_COLL_SETATTR = 24,  // cid, attrname, bl
OP_COLL_RMATTR =  25,  // cid, attrname
OP_COLL_SETATTRS = 26,  // cid, attrset
OP_COLL_MOVE =    8,   // newcid, oldcid, oid

OP_STARTSYNC =    27,  // start a sync

OP_RMATTRS =      28,  // cid, oid
OP_COLL_RENAME =       29,  // cid, newcid

OP_OMAP_CLEAR = 31,   // cid
OP_OMAP_SETKEYS = 32, // cid, attrset
OP_OMAP_RMKEYS = 33,  // cid, keyset
OP_OMAP_SETHEADER = 34, // cid, header
OP_SPLIT_COLLECTION = 35, // cid, bits, destination
OP_SPLIT_COLLECTION2 = 36, /* cid, bits, destination
doesn't create the destination */
OP_OMAP_RMKEYRANGE = 37,  // cid, oid, firstkey, lastkey
OP_COLL_MOVE_RENAME = 38,   // oldcid, oldoid, newcid, newoid

OP_SETALLOCHINT = 39,  // cid, oid, object_size, write_size
OP_COLL_HINT = 40, // cid, type, bl
};
// ...
}


每一个操作都在事务类中有一个对应的函数实现(如 OP_ZERO:
zero(cid, oid off, len)


一个事务可以有如下三个回调:

on_applied


on_commit


on_applied_sync


ObjectStore::Transaction
对象主要用来发送来自OSD的操作序列。例如,
OSD:mkfs
执行下述操作来初始化meta集合:

ObjectStore::Transaction t;
t.create_collection(META_COLL);
t.write(META_COLL, OSD_SUPERBLOCK_POBJECT, 0, bl.length(), bl);
ret = store->apply_transaction(t);


ObjectStore::Transaction
类还能从Buffer中反序列出操作序列(注:即从字节流重建Transcation对象)。日志重做机制就是使用这种方式来重做事务(注:从日志中读取字节流重建出Transcation对象,再Apply这个对象)。

日志

日志对故障恢复很重要。基类
ObjectStore
没有实现日志功能。在子类
JournalingObjectStore
中添加了日志能力。



JournalingObjectStore
中添加了如下方法:

journal_start

journal_stop

journal_write_close

journal_replay

更要的是:

_op_journal_transactions - 添加事务到日志

do_transactions - 应用日志的纯虚函数.
mount
过程中的
replay_journal
中有一个调用例子。

实现

当前只有一个
Journal
实现:



ObjectStore 实现

FileStore

由于
KeyValueStore
还处于实验阶段,而
MemStore
更多的还是一种参考/demo实现,
FileStore
成为目前使用最广的一种实现。



FileStore
实现了
JournalingObjectStore
类,相应地也就实现了
ObjectStore
类。该类既实现了
ObjectStore::Transaction
中的操作也实现了其他成员操作。事务操作在
_do_transaction
中实现并分发给
_$OPERATION
方法完成具体的工作。由于每个文件系统的特性不同,有些操作及特性检查方法被提取出来放到了抽象类
FileStoreBackend
中。一个与文件系统代码相关的特殊操作是:
fiemap


关于fiemap

fiemap允许你访问文件的扩展数据。基本上,你请求Linux系统将指向文件数据区的索引返回给你。这对稀疏文件很有用。Ceph FileStore在
FileStore::_do_sparse_copy_range
中使用了它。

延伸阅读:

LWN: Fiemap, an extend mapping ioctl

GNU Coreutils copy implementation

FileStore后端

FileStore后端将大部分与文件系统相关的优化和生僻特性从FileStore的实现中抽象剥离。如果底层的文件系统支持检查点,FileStore后备将使用文件系统的快照特性实现检查点。它还会执行特征检查,如检测是否支持fiemap。所有的具体类都继承至共同的基类
GenericFileStoreBackend


特定文件系统的支持情况:

ZFS - 用ZFS快照实现检查点

XFS - 通过
set_alloc_hint
设置XFS扩展大小

Btrfs - 用Btrfs快照实现检查点。用COW实现高效的文件克隆

KeyValueStore

KeyValueStore
ObjectStore
的一个适配类同时是
KeyValueDB
的一个具体子类。
KeyValueDB
是KV数据库的一个通用接口类,在Ceph代码的其他地方也有用到它。适配器中最大的一部分操作是将使用集合id及对象id的类文件系统操作映射为扁平的KV接口。KV数据库中的键值不是通常的任意大小,因此,KV映射及键值的条带化都需要类
StripObjectMap
来完成,它是
KeyValueStore
的一部分。

对象映射



GenericObjectMap
ghobject_t
coll_t
到KV映射器的公共基类。它有点类似于
KeyValueDB
API,但并没有实现它。而是采用
KeyValueDB
代理实现。

StripObjectMap

StripObjectMap
KeyValueStore
源码的一部分并且实现了
GenericObjectMap
。它添加了条带和缓存功能。默认条带大小为4096字节(可配置)。

数据库后端



kinetic 希捷kinetic客户端github repository

leveldb Google LevelDB

rocksdb Facebook RocksDB

MemStore

MemStore将一切都存储在内存,在mount/umount时支持转储和恢复。为便于对象和组查找,它围绕着C++对象及哈希表来构建。

与它的实现相关的第一条提交记录是对ObjectStore 1的一种参数实现。该实现仍然是1,537 SLOC.

如何添加新的ObjectStore

由于已经有处理文件系统和KV数据库的代码,写一个全新的ObjectStore不总是有必要。

一个粗略的指南告诉你从哪里开始:

想支持的是何种后端?

KV数据库: 从
KeyValueDB
的一个实现开始(注:参考LevelDBStore.cc/h 和 RocksDBStore.cc/h)

文件系统:

看下
FileStoreBackend
中的
detect_features
方法。文件系统是否需要特殊处理?

是否支持快照?如果是,参考
BtrfsFileStoreBackend
ZFSFileStoreBackend


完全不一样的实现?看看
MemStore
(注:以了解需要实现哪些方法,以及这些方法最简单的的原型实现)。

#

https://github.com/ceph/ceph/commit/aa63d6730a638591b0699c4215ed5cce2917d1c9↩
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息