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