1、簡介
列族(Column Families)是rocksdb3.0提出的一個機制,用於對同一個數據庫的記錄(鍵值對)進行邏輯划分。默認情況下所有的記錄
都會存儲在一個默認列族里(ROCKSDB_NAMESPACE::kDefaultColumnFamilyName)
列族具有的屬性
1)可以跨列族進行原子寫,彌補了rocksdb在單個進程內只能操作一個數據庫的問題。
2)在不同的列族,提供數據庫的一致性視圖
3)可以對列族進行獨立配置
4)動態添加和drop列族
2、使用
1)列族的配置
Options, ColumnFamilyOptions, DBOptions
ColumnFamilyOptions用於配置列族,DBOptions用於數據庫粒度的配置,Options繼承了ColumnFamilyOptions, DBOptions,
因此Options可以執行上述兩種配置。
2)主要操作
每個列族通過句柄類ColumnFamilyHandle進行操作,包括列族的創建和銷毀都要使用ColumnFamilyHandle完成。
創建列族,
下列代碼就創建了一個名為"new_cf"的列族
ColumnFamilyHandle *handl;
db->CreateColumnFamily(ColumnFamilyOptions(), "new_cf", &handl);
db->DestroyColumnFamilyHandle(handl);
使用列族,
基於列族打開數據庫,和常規的方式不同。具體來說,如果我們以讀寫模式打開數據庫,則必須要給open傳入所有的列族,
否則open方法會返回Status::InvalidArgument()。每個列族通過ColumnFamilyDescriptor表示,這個類包含了
{列族名,ColumnFamilyOptions}。下列代碼通過讀寫模式打開了一個包含所有列族的數據庫:
vector<ColumnFamilyDescriptor> colume_families;
colume_families.push_back(ColumnFamilyDescriptor(ROCKSDB_NAMESPACE::kDefaultColumnFamilyName, ColumnFamilyOptions()));
colume_families.push_back(ColumnFamilyDescriptor("new_cf"), ColumnFamilyOptions())
vector<ColumnFamilyHandle *> cf_handles;
Status s = db->open(DBOptions(), DB_PATH, colume_families, &cf_handles, &db);
如果使用只讀模式打開數據庫,那么可以只傳入我們需要讀取的列族,不過默認的列族是必須要傳入給open函數的
// open db read only
column_families.push_back(ColumnFamilyDescriptor("new_cf", ColumnFamilyOptions()));
column_families.push_back(ColumnFamilyDescriptor(kDefaultColumnFamilyName, ColumnFamilyOptions()));
s = DB::OpenForReadOnly(DBOptions(), kDBPath, column_families, &handles, &db);
assert(s.ok());
s = db->Get(ReadOptions(), handles[0], Slice("key2"), &value1);
assert(s.ok());
3) WriteBatch
通過WriteBatch我們可以原子的操作不同的列族,例如可以通過handles[0]去刪除handles[1]插入的鍵值對{"key": "value"}
// put and get from non-default column family
s = db->Put(WriteOptions(), handles[1], Slice("key"), Slice("value"));
assert(s.ok());
std::string value;
s = db->Get(ReadOptions(), handles[1], Slice("key"), &value);
assert(s.ok());
// atomic write
WriteBatch batch;
batch.Put(handles[0], Slice("key2"), Slice("value2"));
batch.Put(handles[1], Slice("key3"), Slice("value3"));
batch.Delete(handles[0], Slice("key"));
s = db->Write(WriteOptions(), &batch);
assert(s.ok());
3、原理和實現
簡單的說,不同的列族是共享WAL的,但是memtable和SST file是隔離的。
