Google leveldb學習筆記一:基本架構與安裝使用
阿新 • • 發佈:2018-12-28
簡介
LevelDB是一個Google編寫的快速鍵值儲存庫,它提供從字串鍵到字串值的有序對映。
基本架構
LSM樹儲存引擎
先說什麼是儲存引擎:
- 儲存引擎是儲存系統的發動機,直接決定了儲存系統能夠提供的效能和功能
儲存系統的基本功能包括:增刪讀改,讀取操作又可以分為隨機讀取和順序掃描
- 雜湊儲存引擎是雜湊表的持久化表現,不支援順序掃描,對應的儲存系統為鍵值儲存系統
- B-Tree儲存引擎是B-Tree的持久化實現,支援順序掃描,對應的儲存系統為關係資料庫
- LSM樹儲存引擎和B-Tree支援順序掃描,它通過批量轉儲技術規避磁碟隨機寫入問題
LevelDB的LSM儲存引擎
LSM樹的想法很簡單,就是將對資料的修改增量保持在記憶體中,達到能指定的大小限制後將這些修改操作批量寫入磁碟,讀取時需要合併磁碟中的歷史資料和記憶體中最近的修改操作。LSM樹有效的規避了磁碟隨機寫入的問題,丹讀取時可能需要訪問較多的磁碟檔案
儲存結構
- 如圖所示,LevelDB儲存引擎主要包括:記憶體中的MemTable和不可變MemTable以及磁碟上的幾種主要檔案;當前檔案、清單檔案、操作日誌檔案以及SSTable檔案
- 當引用寫入一條記錄時,LevelDB會首先將修改操作寫入到操作日誌檔案,成功後再將操作應用到MemTable,這樣就完成了寫入操作。
當MemTable佔用的記憶體到達一個上限值後,需要將記憶體的資料轉儲到外存檔案中
LevelDB會將原先的MemTable凍結成為不可變MemTable,並生成一個新的MemTable
新到來的資料被記入新的操作日誌檔案和新生成的MemTable中
LevelDB後臺執行緒將不可變MemTable的資料排序後轉出到磁碟,形成一個新的SSTable檔案,註冊操作成為Compaction
SSTable檔案是記憶體中的資料不斷進行Compaction操作後形成的
SSTable中的檔案是按照記錄的主鍵排序的,每個檔案中都有最小的主鍵和最大的主鍵
LevelDB的寫入操作很簡單,但讀取操作比較複雜,需要在記憶體以及各個層級檔案中按照從新到老一次查詢,為了加快速度,LevelDB內部會執行Compaction操作來對已有的記錄進行整理壓縮,從而刪除一些不再有效的記錄,減少資料規模和檔案數量
安裝和使用
下載後解壓
下載地址
LevelDB只支援POSIX系統,如Linux和Mac等
編譯
cd leveldb-1.20
make
安裝
sudo cp -r leveldb-1.20/include/leveldb/ /usr/include/
sudo cp leveldb-1.20/out-shared/libleveldb.so.1.20 /usr/lib
sudo ln -s /usr/lib/libleveldb.so.1.20 /usr/lib/libleveldb.so.1
sudo ln -s /usr/lib/libleveldb.so.1.20 /usr/lib/libleveldb.so
sudo ldconfig
測試程式
#include <assert.h>
#include <string.h>
#include <leveldb/db.h>
#include <iostream>
using namespace leveldb;
using namespace std;
int main(int argc, char** argv)
{
DB* db;
Options options;
// 如果開啟已存在資料庫的時候,需要丟擲錯誤,將以下程式碼插在DB::Open方法前面
options.create_if_missing = true;
// 開啟一個數據庫例項
Status status = DB::Open(options, "/tmp/testdb", &db);
assert(status.ok());
// LevelDB提供了Put、Get和Delete三個方法對資料庫進行新增、查詢和刪除
string key = "Hello";
string value = "leveldb";
// 新增key=value
status = db->Put(WriteOptions(), key, value);
assert(status.ok());
// 根據key查詢value
status = db->Get(ReadOptions(), key, &value);
assert(status.ok());
cout << "key = " << key << endl;
cout << "value = " << value << endl;
// 刪除key
status = db->Delete(WriteOptions(), key);
// 查詢key
status = db->Get(ReadOptions(), key, &value);
if (!status.ok()) {
cerr << key << ": " << status.ToString() << endl;
} else {
cout << key << "==" << value << endl;
}
delete db;
return 0;
}
all:
g++ -g -Wall -o test test.cpp -lleveldb
clean:
rm test
注意:要加上鍊接庫-lleveldb
執行結果:
key = Hello
value = leveldb
Hello: NotFound:
現在leveldb就已經安裝成功了