CEPH OBJECTSTORE API介紹

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 cidghobject_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

KeyValueStoreObjectStore的一個適配類同時是KeyValueDB的一個具體子類。KeyValueDB是KV數據庫的一個通用接口類,在Ceph代碼的其他地方也有用到它。適配器中最大的一部分操作是將使用集合id及對象id的類文件系統操作映射爲扁平的KV接口。KV數據庫中的鍵值不是通常的任意大小,因此,KV映射及鍵值的條帶化都需要類StripObjectMap來完成,它是KeyValueStore的一部分。

對象映射

GenericObjectMapghobject_tcoll_t到KV映射器的公共基類。它有點類似於KeyValueDB API,但並沒有實現它。而是採用KeyValueDB代理實現。

StripObjectMap

StripObjectMapKeyValueStore源碼的一部分並且實現了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方法。文件系統是否需要特殊處理?
    • 是否支持快照?如果是,參考BtrfsFileStoreBackendZFSFileStoreBackend
  • 完全不一樣的實現?看看MemStore(注:以瞭解需要實現哪些方法,以及這些方法最簡單的的原型實現)。

#

  1. https://github.com/ceph/ceph/commit/aa63d6730a638591b0699c4215ed5cce2917d1c9↩
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章