實(shí)現(xiàn)一個(gè)開(kāi)源KV數(shù)據(jù)庫(kù)的想法來(lái)源于對(duì)目前項(xiàng)目中所使用的K-V數(shù)據(jù)庫(kù)使用情況的不滿(mǎn)意。
先介紹一下我們的目前項(xiàng)目,作為本文的背景:
較為底層的分布式運(yùn)行平臺(tái),使用C/C++實(shí)現(xiàn)的Actor模型(異步消息傳遞系統(tǒng))
數(shù)據(jù)schema簡(jiǎn)單靈活,使用key-value能夠很好表示。
數(shù)據(jù)庫(kù)有大量的讀寫(xiě)請(qǐng)求,有事務(wù)需求,數(shù)據(jù)丟失容忍度很低。
當(dāng)前,從眾多的KV和NOSQL存儲(chǔ)產(chǎn)品中,我們使用了Berkeley DB作為底層的存儲(chǔ)引擎。
為什么選擇BDB呢?
1.與傳統(tǒng)的RDBMS相比,簡(jiǎn)單K-V存儲(chǔ)的Berkeley DB(再加入“嵌入式”直接庫(kù)鏈接的特性)有著優(yōu)越的性能,容易滿(mǎn)足我們大量讀寫(xiě)(尤其是大量寫(xiě))的需求。
2.作為一個(gè)嵌入式的K-V數(shù)據(jù)庫(kù),Berkeley DB歷史悠久(目前由Oracle所有),穩(wěn)定且久經(jīng)考驗(yàn),文檔豐富,輔助工具全面。這是我們之所以在眾多的開(kāi)源K-V(Nosql)數(shù)據(jù)庫(kù)中選擇BDB的首要原因:靠譜。
3.第三個(gè)選擇BDB的原因是事務(wù)支持:作為為數(shù)不多的能夠提供ACID事務(wù)支持的K-V數(shù)據(jù)庫(kù),BDB對(duì)事務(wù)支持提供了豐富的支持:從不同的隔離級(jí)別、不同的持久化保證以及分布式事務(wù)2PC的prepare模型等,可配置程度很高。
BDB哪些方面不能達(dá)到我們的需求?
1.仍然是性能。作為K-V數(shù)據(jù)庫(kù),BDB的性能依然達(dá)不到我們的目標(biāo):由于有足夠大的內(nèi)存作為緩存,讀操作的性能基本沒(méi)問(wèn)題,但寫(xiě)操作(尤其是大量應(yīng)用的事務(wù)寫(xiě))的性能堪憂(yōu)。
使用Auto-commit(每條寫(xiě)作為一個(gè)獨(dú)立的事務(wù)),一條記錄的寫(xiě)延時(shí)接近于1~10ms。
顯示開(kāi)啟事務(wù)后,寫(xiě)操作有了極大改善:10~100us(因?yàn)椴恍枰磿r(shí)sync到硬盤(pán)),但事務(wù)提交操作依然極為耗時(shí)。
有人可能會(huì)說(shuō),你可以調(diào)節(jié)BDB事務(wù)的持久化保證的程度,比如在提交時(shí)設(shè)置:
DB_TXN_WRITE_NO_SYNC,在提交時(shí)只寫(xiě)log到硬盤(pán),不sync(只有OS Crash才會(huì)丟數(shù)據(jù))
或者更快一些,使用DB_TXN_NOSYNC,連同步調(diào)syscall write的開(kāi)銷(xiāo)都省下來(lái)(但App crash可能會(huì)丟數(shù)據(jù))