衆所周知,leveldb是Google的Sanjay Ghemawat和Jeff Dean兩位大神編寫的一個高性能KV引擎,使用起來很是方便。然而,開源版本的leveldb將全部數據存放在了本地磁盤,若是本地磁盤發生故障,可能致使部分甚至所有數據丟失(例如MANIFEST丟失),這對於使用者來講無疑會帶來災難性的後果。在這時,數據的高可靠便成爲了一個相當重要的問題,本篇博文將帶你五分鐘快速實現leveldb中數據存儲的高可靠。git
百度開源的分佈式文件系統BFS(開源地址:https://github.com/baidu/bfs)提供了mount工具,能夠將整個分佈式文件系統直接掛載到本地目錄,從而能夠像操做本地文件同樣來操做分佈式文件系統中的文件,咱們能夠利用分佈式文件系統自己提供的數據高可靠特性來保證leveldb中數據的安全。github
1. 首先下載BFS源碼數據庫
git clone git@github.com:baidu/bfs.git
安全
2. 而後編譯所須要的二進制文件負載均衡
cd bfs; make && make bfs_mount
分佈式
編譯完成後,會在當前目錄下生成啓動BFS所須要的nameserver
、chunkserver
二進制,以及掛載工具bfs_mount
工具
3. 啓動BFS集羣(本地模擬分佈式環境)性能
cd sandbox; ./depoly.sh; ./start_bfs.sh
debug
執行成功後,會在本地啓動一個包含一個Nameserver,4個Chunkserver的小集羣,其中Nameserver佔用的端口爲8827日誌
4. 將BFS集羣掛載到本地
cd ../; mkdir bfs_dir; nohup ./bfs_mount -d ./bfs_dir -c localhost:8827 -p / 1>fuse_mount.log 2>&1 &
其中,-d
表示輸出debug日誌,./bfs_dir
表示將BFS掛載到本地的bfs_dir
目錄下,-c localhost:8827
指明瞭BFS集羣的地址,上一步中的start_bfs.sh
會在本地的8827端口啓動BFS的Nameserver,-p /
指定將BFS的根目錄進行掛載
至此,與BFS所作的相關準備工做已經所有完成~
接下來,能夠將本身程序中leveldb的數據寫到BFS中,若是有不熟悉leveldb的同窗,能夠參考下面的使用示例:
#include <stdio.h> #include <leveldb/db.h> int main() { leveldb::DB* db_; leveldb::Options options; options.create_if_missing = true; leveldb::Status s = leveldb::DB::Open(options, "./bfs_dir/ldb_data/", &db_); if (!s.ok()) { printf("Open db fail\n"); return -1; } std::string test_key("hello"), test_value("world"); s = db_->Put(leveldb::WriteOptions(), test_key, test_value); if (!s.ok()) { printf("Write db fail\n"); return -1; } return 0; }
到這裏是否是有點小激動?即便本地磁盤掛掉,BFS自動會進行副本恢復,保證數據不丟失。
更重要的是,只要在其它機器上一樣掛載BFS相應目錄,即可以不須要任何代價的,在另外的機器上對一樣一個leveldb進行操做。(鑑於同一個leveldb同一時刻只容許被一個進程打開,前提須要此機器已經正確的將本身打開的leveldb關閉)這樣,就至關於數據毫無代價的從一臺機器『遷移』到了另一臺機器,是否是很炫酷?可能有些同窗發現了什麼:對,其實BigTable的模型正是如此~ 若是有但願繼續深刻了解的同窗,能夠移步百度開源的,目前已經存儲了萬億級別網頁數據的分佈式數據庫Tera(開源地址:http://github.com/baidu/tera),正是經過相似的原理,在保證數據安全的狀況下,能夠實現快速的負載均衡,分裂合併等特性。