谷歌這個(gè)牛逼的開(kāi)源數(shù)據(jù)庫(kù),我居然等到它上Github熱榜才發(fā)現(xiàn)
今天要和大家分享一個(gè)谷歌開(kāi)源多年,但依舊扛打,最近還登上Github熱榜的kv數(shù)據(jù)庫(kù)——LevelDB。
Leveldb是一個(gè)google實(shí)現(xiàn)的非常高效的kv數(shù)據(jù)庫(kù),創(chuàng)建者是大名鼎鼎的 Jeff Dean 和 Sanjay Ghemawat,目前的版本1.2能夠支持billion級(jí)別的數(shù)據(jù)量了。在這個(gè)數(shù)量級(jí)別下還有著非常高的性能,主要?dú)w功于它的良好的設(shè)計(jì)。
LevelDB 是單進(jìn)程的服務(wù),性能非常之高,在一臺(tái)4個(gè)Q6600的CPU機(jī)器上,每秒鐘寫(xiě)數(shù)據(jù)超過(guò)40w,而隨機(jī)讀的性能每秒鐘超過(guò)10w。具有以下功能特性:
- key和value可以是字符串或者字節(jié)流
- 數(shù)據(jù)按key排列,有序存儲(chǔ)
- 調(diào)用方可以重載排序方法,以實(shí)現(xiàn)自定義排序
- 基本操作只有3種:Put(key, value)、Get(key)、Delete(key)
- 提供原子批量修改接口
- 支持?jǐn)?shù)據(jù)快照
- 支持向前和向后的迭代器
- 支持?jǐn)?shù)據(jù)自動(dòng)壓縮,使用的是snappy壓縮算法
- 和操作系統(tǒng)之間的外部交互是通過(guò)虛接口(virtual interface)來(lái)進(jìn)行,這樣用戶(hù)就能定制化這些交互了
levelDB特牛,但是,再好的工具也有它的局限性,LevelDB 的局限性也很明顯:
- 這不是一個(gè) SQL 數(shù)據(jù)庫(kù),它沒(méi)有關(guān)系數(shù)據(jù)模型,不支持 SQL 查詢(xún),也不支持索引。
- 同時(shí)只能有一個(gè)進(jìn)程(可能是具有多線程的進(jìn)程)訪問(wèn)一個(gè)特定的數(shù)據(jù)庫(kù)。
- 該程序庫(kù)沒(méi)有內(nèi)置的 client-server 支持,有需要的用戶(hù)必須自己封裝。
LevelDB的使用方法
打開(kāi)數(shù)據(jù)庫(kù)
leveldb數(shù)據(jù)庫(kù)的名稱(chēng)與文件系統(tǒng)目錄相對(duì)應(yīng)。數(shù)據(jù)庫(kù)的所有內(nèi)容都存儲(chǔ)在此目錄中。以下示例顯示了如何打開(kāi)數(shù)據(jù)庫(kù):
- #include <cassert>
- #include "leveldb/db.h"
- leveldb::DB* db;
- leveldb::Options options;
- options.create_if_missing = true;
- leveldb::Status status = leveldb::DB::Open(options, "/tmp/testdb", &db);
- assert(status.ok());
- ...
如果要在數(shù)據(jù)庫(kù)已經(jīng)存在的情況下引發(fā)錯(cuò)誤,請(qǐng)?jiān)趌eveldb::DB::Open調(diào)用之前添加以下行:
- options.error_if_exists = true;
關(guān)閉數(shù)據(jù)庫(kù)
完成數(shù)據(jù)庫(kù)操作后,只需刪除數(shù)據(jù)庫(kù)對(duì)象。例子:
- ... open the db as described above ...
- ... do something with db ...
- delete db;
讀寫(xiě)
數(shù)據(jù)庫(kù)提供了Put,Delete和Get方法來(lái)修改/查詢(xún)數(shù)據(jù)庫(kù)。如下:
- std::string value;
- leveldb::Status s = db->Get(leveldb::ReadOptions(), key1, &value);
- if (s.ok()) s = db->Put(leveldb::WriteOptions(), key2, value);
- if (s.ok()) s = db->Delete(leveldb::WriteOptions(), key1);
并發(fā)
一個(gè)數(shù)據(jù)庫(kù)同時(shí)只能被一個(gè)進(jìn)程打開(kāi)。leveldb 會(huì)從操作系統(tǒng)獲取一把鎖來(lái)防止多進(jìn)程同時(shí)打開(kāi)同一個(gè)數(shù)據(jù)庫(kù)。在單個(gè)進(jìn)程中,同一個(gè) leveldb::DB 對(duì)象可以被多個(gè)并發(fā)線程安全地使用,也就是說(shuō),不同的線程可以在不需要任何外部同步原語(yǔ)的情況下,寫(xiě)入、獲取迭代器或者調(diào)用 Get(leveldb 實(shí)現(xiàn)會(huì)確保所需的同步)。但是其它對(duì)象,比如 Iterator 或者 WriteBatch 需要外部自己提供同步保證,如果兩個(gè)線程共享此類(lèi)對(duì)象,需要使用自己的鎖進(jìn)行互斥訪問(wèn)。具體見(jiàn)對(duì)應(yīng)的頭文件。
目前,leveldb已經(jīng)在Github上標(biāo)星 24.2K,累計(jì)標(biāo)星 5.3K(Github地址:https://github.com/google/leveldb)。

































