1. 程式人生 > >Google leveldb學習筆記一:基本架構與安裝使用

Google leveldb學習筆記一:基本架構與安裝使用

簡介

LevelDB是一個Google編寫的快速鍵值儲存庫,它提供從字串鍵到字串值的有序對映。

基本架構

LSM樹儲存引擎

先說什麼是儲存引擎

  • 儲存引擎是儲存系統的發動機,直接決定了儲存系統能夠提供的效能和功能
  • 儲存系統的基本功能包括:增刪讀改,讀取操作又可以分為隨機讀取和順序掃描

    1. 雜湊儲存引擎是雜湊表的持久化表現,不支援順序掃描,對應的儲存系統為鍵值儲存系統
    2. B-Tree儲存引擎是B-Tree的持久化實現,支援順序掃描,對應的儲存系統為關係資料庫
    3. 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就已經安裝成功了