タグ: Ceph 12.2.4
BlueStoreスペースの初期化
BlueStoreのディスク容量管理
概要
- OSD マウント ディレクトリはファイル システムに基づいて管理され、Slow、WAL、DB 領域はベア ディスクに基づいて管理されます。
- 低速領域: このタイプのスペースは主にオブジェクト データの保存に使用され、BlueStore によって管理されます。BlueStore は、BlueFS スペース セグメントに割り当てられ、bluefs_extents 構造を使用して管理されます。
- WAL 領域: BlueFS 単独で管理され、BlueStore には表示されません。BlueFS 自体が電源投入時の初期化を担当します。.log ファイルおよび自身で生成されたログについては、BlueFS は WAL タイプのデバイス空間を使用することを好みます。それが存在しない場合、またはWAL デバイスのスペースが不十分な場合は、段階的にダウングレードして DB および SLOW パーティションを選択します。
- DB 領域: BlueFS のみによって管理され、BlueStore には表示されません。BlueFS 自体が電源投入時の初期化を担当します。.sst ファイルの場合は、DB タイプのデバイス領域が優先されます。それが存在しない場合、または DB デバイス領域が不十分な場合は、低速タイプのデバイススペース。
- rocksdb: ファイル システム KV ストレージ エンジンに基づいて、外部インターフェイスは BlueStore によって呼び出されます。
- BlueStore は、rocksdb をサポートし、小規模ファイル システム BlueFS を実現し、rocksdb の基礎となるシステム パッケージを提供する BlueRocksEnv を実現します。
- BlueFS: フラットなディレクトリとファイル階層 (ツリー状) の組織構造。特定のファイルを見つけるには 2 つの検索が必要です: dir_map を通じてファイルが置かれている最下位のフォルダーを検索し、そのフォルダーの下の file_map で対応するファイルを検索します。 bluefs_fnode_t 構造管理では、extents 属性はディスク上の物理セグメント コレクションを示し、prefer_bdev 属性はファイルを保存するための優先ブロック デバイスを示します。エクステント コレクション内の各エクステントの bdev 属性は、所属するデバイスを識別し、各ファイルは使用できます。複数の異なるブロック、デバイス (WAL、DB、および Slow) スペース、BlueFS:_allocate メソッドで各エクステントの bdev_ 属性値を指定、電源を再度オンにし、DB パーティションの 2 番目の 4K ストレージ スペース (スーパーブロック) を介してエントリ位置を固定します。 BlueFS::_replay を介して読み取り、ログ ファイルのコンテンツを再生すると、メタデータ (dir_map、file_map) が復元されます。
初期化プロセス
[ceph_osd.cc]
int main(int argc, const char **argv)
>> OSD::mkfs(g_ceph_context, store, g_conf->osd_data, mc.monmap.fsid, whoami);
[OSD.cc]
int OSD::mkfs(CephContext *cct, ObjectStore *store, const string &dev, uuid_d fsid,
int whoami)
>> store->mkfs();
>> store->mount();
[BlueStore.cc]
int BlueStore::mkfs()
>> _setup_block_symlink_or_file("block", cct->_conf->bluestore_block_path,
cct->_conf->bluestore_block_size, cct->_conf->bluestore_block_create);
>> _setup_block_symlink_or_file("block.wal", cct->_conf->bluestore_block_wal_path,
cct->_conf->bluestore_block_wal_size, cct->_conf->bluestore_block_wal_create);
>> _setup_block_symlink_or_file("block.db", cct->_conf->bluestore_block_db_path,
cct->_conf->bluestore_block_db_size, cct->_conf->bluestore_block_db_create);
>> _open_db(true);
>> _open_fm(true); 初始化FreelistManager
[BlueStore.cc]
int BlueStore::_open_db(bool create)
>> if (do_bluefs):
>> bluefs = new BlueFS(cct);
>> bluefs->add_block_device(BlueFS::BDEV_DB, bfn);
>> if (create): bluefs->add_block_extent(BlueFS::BDEV_DB, SUPER_RESERVED,
bluefs->get_block_device_size(BlueFS::BDEV_DB) - SUPER_RESERVED);
>> if (create):
>> bluefs->add_block_extent(bluefs_shared_bdev, start, initial);
>> bluefs_extents.insert(start, initial);
>> if (create):
>> bluefs->add_block_extent(BlueFS::BDEV_WAL, BDEV_LABEL_BLOCK_SIZE,
bluefs->get_block_device_size(BlueFS::BDEV_WAL) - BDEV_LABEL_BLOCK_SIZE);
>> if (create): bluefs->mkfs(fsid);
>> bluefs->mount();
[BlueFS.cc]
int BlueFS::mkfs(uuid_d osd_uuid)
>> _init_alloc();
>> 设置superblock信息
>> 初始化log_file
[BlueFS.cc]
int BlueFS::mount()
>> _init_alloc();
>> _replay(false);
>> for (auto& p : file_map):
for (auto& q : p.second->fnode.extents):
alloc[q.bdev]->init_rm_free(q.offset, q.length);
>> log_writer = _create_writer(_get_file(1));
[BlueFS.cc]
int BlueFS::_replay(bool noop)
>> 逐个回放事务op
BlueStore は、rocksdb 関連のインターフェイスを呼び出します
RocksDBStore は KeyValueDB インターフェイスを実装し、BlueStore は RocksDBStore を通じて Rocksdb 操作を実装します。
オープン操作
[BlueStore.cc]
int BlueStore::_open_db(bool create)
>> db = KeyValueDB::create(cct, kv_backend, fn, static_cast<void*>(env));
>> if (create): db->create_and_open(err);
[RocksDBStore.cc]
int RocksDBStore::create_and_open(ostream &out)
>> do_open(out, true);
[RocksDBStore.cc]
int RocksDBStore::do_open(ostream &out, bool create_if_missing)
>> rocksdb::DB::Open(opt, path, &db);
読み取り操作
[BlueStore.cc]
int BlueStore::read(const coll_t& cid, const ghobject_t& oid,
uint64_t offset, size_t length, bufferlist& bl, uint32_t op_flags)
>> read(c, oid, offset, length, bl, op_flags);
[BlueStore.cc]
int BlueStore::read(CollectionHandle &c_, const ghobject_t& oid,
uint64_t offset, size_t length, bufferlist& bl, uint32_t op_flags)
>> OnodeRef o = c->get_onode(oid, false);
>> _do_read(c, o, offset, length, bl, op_flags);
[注]
每个Onode包含一个ExtentMap,每个ExtentMap包含若干个Extent,
每个Extent负责管理一段逻辑范围内的数据并管理一个Blob,
由Blob通过若干个pextent负责将数据映射到磁盘
[BlueStore.cc]
BlueStore::OnodeRef BlueStore::Collection::get_onode(const ghobject_t& oid, bool create)
>> store->db->get(PREFIX_OBJ, key.c_str(), key.size(), &v);
[KeyValueDB.h]
virtual int get(const string &prefix,const char *key, size_t keylen, bufferlist *value)
>> get(prefix, string(key, keylen), value);
[KeyValueDB.h]
virtual int get(const std::string &prefix, const std::string &key, bufferlist *value)
>> get(prefix, ks, &om);
[RocksDBStore.cc]
int RocksDBStore::get(const string &prefix,
const string &key, bufferlist *out)
>> db->Get(rocksdb::ReadOptions(), rocksdb::Slice(k), &value);
書き込み操作
[BlueStore.cc]
void BlueStore::_kv_sync_thread()
>> db->submit_transaction_sync(synct);
[KeyValueDB.h]
virtual int submit_transaction_sync(Transaction t)
>> submit_transaction(t);
[RocksDBStore.cc]
int RocksDBStore::submit_transaction(KeyValueDB::Transaction t)
>> db->Write(woptions, &_t->bat);
削除操作
指定されたメタデータのキーと値のペアをデータベースから削除します
[BlueStore.cc]
int BlueStore::_remove(TransContext *txc, CollectionRef& c, OnodeRef &o)
>> _do_remove(txc, c, o);
[BlueStore.cc]
int BlueStore::_do_remove(TransContext *txc,
CollectionRef& c, OnodeRef o)
>> txc->t->rmkey(PREFIX_OBJ, o->key.c_str(), o->key.size());
[KeyValueDB.h]
virtual void rmkey(const std::string &prefix,
const char *k, size_t keylen)
>> rmkey(prefix, string(k, keylen));
[RocksDBStore.cc]
void RocksDBStore::RocksDBTransactionImpl::rmkey(const string &prefix, const string &k)
>> bat.Delete(combine_strings(prefix, k));
コンパクトな操作性
OSD 関連のコマンド (asok_command) はクライアント コマンド ラインで使用できます。
[BlueStore.h]
void compact() override
>> db->compact();
[RocksDBStore.cc]
void RocksDBStore::compact()
>> db->CompactRange(options, nullptr, nullptr);
【参考文献】
- 「Ceph の設計原則と実装」第 2 章 パフォーマンスのピーク — 新しいオブジェクト ストレージ エンジン BlueStore