leveldb 是一套 key-value 的資料存取工具,leveldb會將資料儲存在檔案裡,另外也會暫存部分資料在 memory 以加快讀取效率,雖然 leveldb 的名稱中有 db ,不過他的功能跟一般 database 的功能可以差很多的,並且 leveldb 無法遠端來存取資料,也就是非 client-server 的機制,它只能在本機執行,當然你也可以自已幫它寫個 server 去取存囉!! Google 的說明資料中還有一項比較重要的點,[Only a single process (possibly multi-threaded) can access a particular database at a time. ],中文是說一次只能一個 process 存取,看起來像是他會自動 lock , 如果限制一個 process , 這樣就可以百分之分確保一次只有一個 process 在修改資料。
安裝 leveldb
先用 git 從 google repository 將原始碼抓回來,接著使用 make 就能編譯完成囉,預設的 Makefile 裡會使用 static library 方式編譯成 libleveldb.a 的檔案,不過我不喜歡使用 statis library,我喜歡用 shared library ,所以我修改 Makefile 的內容。
- git clone https://code.google.com/p/leveldb/ (取得原始碼)
修改 Makefile 內容
- 106 行 LIBRARY = libleveldb.a 改成 LIBRARY = libleveldb.so
- 121 行 $(AR) -rs $@ $(LIBOBJECTS) 改成 gcc -shared -fPIC -o $@ $(LIBOBJECTS)
改完後,重新 make 就會看到 libleveldb.so 這個檔案了,那就把這個檔案複製到 system link libraries 裡吧,我將 libleveldb,so cp 到 /usr/local/lib ,再把 (leveldb root)/include/leveldb 複製到 /usr/local/include/ ,最後執行 sudo ldconfig,更新系統的 library 進結,這樣就完成 shared library 的 libleveldb 囉,對了你要檢查一下 /etc/ld.so.conf 這檔案裡有沒有包含路徑 /usr/local/lib。
- make
- cp libleveldb /usr/local/lib/
- cp -r include/leveldb /usr/local/include/
- sudo ldconfig
leveldb 使用方式
基本功能有新增,刪除,修改,取得資料,使用方式很簡單,先要知道 leveldb的 namespace 是 「leveldb」,所以呼叫它的功能時,都要加上 「leveldb::」,接下來介紹一些簡單的使用方式。
- 宣告 leveldb : leveldb::DB *db;
- 宣告 leveldb option : leveldb::Options option;
- 打開 leveldb : leveldb::DB::Open(option,"/tmp/leveldb_t",&db);
- 寫入一個 key : db->Put(leveldb::WriteOptions(), key, value);
- 取得一個 key : db->Get(leveldb::ReadOptions(), key, &str); ,str 的型態為 string
實際寫一小段 code 來測試一下存取功能, file:test.cc 。
- #include "leveldb/db.h"
- #include <iostream>
- using namespace std;
- //using namespace leveldb;
- int main(){
- leveldb::DB *db;
- leveldb::Options option;
- option.create_if_missing = true;
- leveldb::DB::Open(option,"/tmp/leveldb_t",&db);
- string key="t2";
- string value="test";
- db->Put(leveldb::WriteOptions(), key, value);
- string res;
- db->Get(leveldb::ReadOptions(), key, &res);
- cout << "get value = " << res << endl;
- delete db;
- return true;
- }
編譯與執行 command 如下:
- g++ test.cc -lleveldb -lpthread
- ./a.out
leveldb options
現在我們來看看 leveldb 有那些 options 可以調整,設定的方式如下。
- leveldb::Options option;
- option.create_if_missing = true;
- create_if_missing : 如果 leveldb 的file 不存在,則自動建立 file。
- error_if_exists : 如果 leveldb 的file 已存在,又嘗試建立的話,則彈出 error。
- write_buffer_size : 預設是 4MB ,儲存在 memory 的最大空間。
- max_open_files : leveldb最多可以使用的檔案數,一個檔案可以儲存 2MB 的資料。
- 寫入時同步 cache 的資料:預設 leveldb 會自動cache key-value 的數值,所以修改 value 時,有可能會因為 cache 的原因,而抓不到最新的 value ,這時可以設定 sync=true,這樣每次更新 value 時,就自動更新 cache 的資料,不過速度上會受到一些影響。
- leveldb::WriteOptions writeable;
- writeable.sync=true;
- db->Put(writeable, key, value);
leveldb效能
Google 自已說 leveldb 執行的速度很快、很優,上面這個連結是他們自已的測試結果,看起來是還蠻快的,不過在處理大 bytes 的數值時,效能就比較差了。