分享一個純 Go 編寫的高效能內嵌型 KV 資料庫 NutsDB,支援事務以及多種資料結構

xujiajun發表於2019-03-12

NutsDB是純Go語言編寫一個簡單、高效能、內嵌型、持久化的key-value資料庫。

NutsDB支援事務,從v0.2.0之後的版本開始支援ACID的特性,建議使用最新的版本。v0.2.0之前的版本,保持高效能,沒有作sync,但是具備高效能的寫(本地測試,百萬資料寫入達40~50W+/s)。所有的操作都在事務中執行。NutsDB從v0.2.0版本開始支援多種資料結構,如列表(list)、集合(set)、有序集合(sorted set)。

專案地址

https://github.com/xujiajun/nutsdb

中文文件

https://github.com/xujiajun/nutsdb/blob/master/README-CN.md

Feature

  • 支援事務
  • 支援基本的Put、Delete、Get操作
  • 支援字首掃描
  • 支援範圍掃描
  • 支援多種資料結構,類似Redis的Api,如列表(list)、集合(set)、有序集合(sorted set)。

目前專案還在試驗階段狀態,沒有經過實際生產環境考驗。歡迎star、提issue,貢獻!

為什麼有NutsDB

對於現狀或多或少的不滿
我想找一個用純go編寫,儘量簡單(方便二次開發、研究)、高效能(讀寫都能快一點)、內嵌型的(減少網路開銷)資料庫,最好支援事務。因為我覺得對於資料庫而言,資料完整性很重要。如果能像Redis一樣支援多種資料結構就更好了。 而像Redis一般用作快取,對於事務支援也很弱。

找到幾個備選項:

BoltDB

BoltDB是一個基於B+ tree,有著非常好的讀效能,還支援很實用的特性:範圍掃描和按照字首進行掃描。有很多專案採用了他。雖然現在官方不維護,由etcd團隊在維護 他也支援ACID事務,但是他的寫效能不是很好。如果對寫效能要求不高也值得嘗試。

GoLevelDB

GoLevelDB是google開源的leveldb的go語言版本的實現。他的效能很高,特別是寫效能,他基於LSM tree實現。可惜他不支援事務。

Badger

Badger同樣是基於LSM tree,不同的是他把key/value分離。據他官網描述是基於為SSD優化。同是他也支援事務。但是我自己測試發現他的寫效能沒我想象中高,具體見我的benchmark。

此外,以上DB都不支援多種資料結構例如list、set等。

好奇心的驅使

對於如何實現kv資料庫的好奇心吧。資料庫可以說是系統的核心,瞭解資料庫的核心或者自己有實現,對更好的用輪子或者下次根據業務定製輪子都很有幫助。

基於以上兩點,我決定嘗試開發一個簡單的kv資料庫,效能要好,功能也要強大(至少他們好的功能特性都要繼承)。

如上面的選項,我發現大致基於儲存引擎的模型分:B+ tree和LSM tree。基於B+ tree的模型相對後者成熟。一般使用覆蓋頁的方式和WAL(預寫日誌)來作崩潰恢復。而LSM tree的模型他是先寫log檔案,然後在寫入MemTable記憶體中,當一定的時候寫回SSTable,檔案會越來越多,於是他一般作法是在後臺進行合併和壓縮操作。 一般來說,基於B+ tree的模型寫效能不如LSM tree的模型。而在讀效能上比LSM tree的模型要來得好。當然LSM tree的模型也可以優化,比如引入BloomFilter。 但是這些模型還是太複雜了。我喜歡簡單,簡單意味著好實現,好維護,相對不容易出錯。

直到我找到bitcask這種模型,他其實本質上也算LSM tree的範疇吧。 他模型非常簡單很好理解和實現,很快我就實現了一個版本。但是他的缺點是不支援範圍掃描。我嘗試去優化他,又開發一個版本,基於B+ tree作為索引,滿足了範圍掃描的問題。現在這個版本基本上都實現上面提到的資料庫的一些有用的特性,包括支援範圍掃描和字首掃描、包括支援bucket、事務等,還支援了更多的資料結構(list、set、sorted set)。

天下沒有銀彈,NutsDB也有他的侷限,比如隨著資料量的增大,索引變大,啟動會慢,只想說NutsDB還有很多優化和提高的空間,由於本人精力以及能力有限。所以把這個專案開源出來。更重要的是我認為一個專案需要有人去使用,有人提意見才會成長。

歡迎star、提issue,貢獻!

相關文章