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正在開發)
相關文檔
代碼
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
中使用了它。
延伸閱讀:
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
(注:以瞭解需要實現哪些方法,以及這些方法最簡單的的原型實現)。