標籤:

如何評價 Badger (fast key-value storage)?

Introducing Badger: A fast key-value store written natively in Go - Dgraph Blog

dgraph-io/badger


樓上各位大師們已經分析的差不多了,LSM-Tree 類的數據結構其實就那麼幾個關鍵點,memtable 的設計(包括各種讀寫 memtable 的性能優化)/ 在 level 間查詢的性能優化(比如 RocksDB 的每個 Level 的 BloomFilter 和 Prefix Hint 等優化) / 還有更重要的就是看 Compaction 的策略,其中 Compaction 對於 workload 是最相關的,你寫入巨大,compact 跟不上神仙都救不了你,基本就是 stall 的命。

不過 badger 的聰明的地方就是, key 的 compaction 和 value 的 gc 分開。

其中 key 的 compaction 的入口在:func (s *levelsController) runWorker(workerID int)

思路也比較簡單,就是從底往上 compact. 沒啥優化,代碼略屎,好處就是簡單粗暴。

value 的 gc 就更粗暴了:func (l *valueLog) runGCInLoop(lc *y.LevelCloser) ,一個 worker 每 10 分鐘,隨便挑個 value file,gc 的過程也比較簡單粗暴,就是掃一遍標記刪除的,然後 compact。

實現都還比較糙,沒啥 tuning point,算是個大點的玩具,存儲引擎用 pure go 寫基本是個坑,實際用的時候 memtable 開大點,海量小對象的 go gc 的問題很難迴避。

這個設計最適合的場景是 key 小 value 大,而且基本就一次寫入,從來不更新的場景。而且 workload 分布相對隨機,否則如果 key 和 value 都很小,那這個設計一定會多出一次 disk io,還不如直接放到 memtable 裡面內存利用率會更高。。。所以啊,存儲引擎設計都是有各種權衡的,沒有什麼包治百病。。。

BTW, badger 的思路很像 rocksdb 的 blob storage(估計大概 2017q3 基本能可用吧), 我其實更看好 rocksdb 這邊的實現。不過 rocksdb team 和社區並沒有花太多時間在各種語言的 binding 上面,api 又過於複雜,c api 不太跟得上,所以其他語言的 binding 做得不太好,這也給 badger 這類小玩具一些生存的空間。就醬。


昨天在Hacker News報道的,很有意思的項目

基本思路是RocksDB基於LevelDB為SSD優化,但不是為SSD尤其是目前超高隨機讀寫能力的NVME SSD設計.目前300-400K IOPS左右隨機讀的設備已經普及,繼續用RocksDB大量耗費順序寫(compaction)的帶寬來減少隨機讀實際變成了一種浪費.

Badger的設計上,是key/value分離,key繼續走LSM,value則就是一個WAL式的value log保存.要使用value的時候,超高隨機讀能力的SSD幫你搞定.這樣幾個好處:LSM小,佔用內存少,因為value不走LSM.反覆順序寫的帶寬節省了,還避免大量fd使用,value本身不出現在多層,read amplification小延遲低.

估計這種態度方法就是名字Badger的由來,有興趣的自行翻牆去youtube看honey badger don"t give a crap視頻.目前作者提供的性能看,range iteration在小value時候性能一塌糊塗,別的基本顯著超過RocksDB.

當然,現在不應該使用badger在生產環境中,embedded kv store基本是底層構件,穩定可靠不丟數據最最重要,rocksdb等一系列成熟的庫被近距離檢驗了無數次,這點不能忽視.目前的benchmark是作者提供的,RocksDB各類配置玩開以後,最後結果應該會和作者目前提供的有差異.

至於什麼Go實現,沒有cgo的問題,這不是關鍵,最多是說go現在的profiler不追到cgo下,進一步profiling有一定麻煩,沒必要對cgo恨的如此這般.


這玩意需要對valuelog做gc,帶來的寫放大也不容忽視,感覺和RocksDB的寫放大相比差不了多少。


這個項目本身就是個玩具,用一個idea加上go語言就開始吹牛逼挺沒意思的,和rocksdb根本不是一個量級的東西。

至於idea本身,實際上很多小文件系統都是類似的思路。本質上就是當value遠大於key的時候把value獨立出來減少compact帶來的io開銷。這個思路其實很直觀而且我相信並不是首創。優點當然顯而易見,問題在於,compact本來就是為了回收被刪掉或者覆蓋的數據以減少空間並且減少文件數以提高性能的。你不對value log做compact的話一旦你的key要頻繁刪除或者覆蓋那就很浪費空間(小文件系統放圖片啥的其實通常很少更新或刪除甚至很多都不讓覆蓋)。也就是應用場景被限制了。不說適用場景就直接比性能都是耍流氓。


看了下,作者的benchmark顯示在大value的情況下效果會更好。不過因為value是WAL log來不斷append的,所以如果有大量的複寫value的話,感覺value log就會很大,而且因為value log不走LSM,所以不會觸發compact,感覺這裡需要手動去compact,不知道這部分的開銷如何。


推薦閱讀:

Key-value資料庫比關係型資料庫更加新嗎?

TAG:資料庫 | LevelDB |