RocksDB介紹:一個比LevelDB更彪悍的引擎

關於LevelDB的資料網上還是比較豐富的,如果你尚未聽說過LevelDB,那請稍微預習一下,因爲RocksDB實際上是在LevelDB之上做的改進。本文主要側重在架構上對RocksDB對LevelDB改進的地方做個簡單介紹並添加一些個人的看法,更詳細的信息讀者可參考其官網:http://rocksdb.org/

RocksDB是在LevelDB原來的代碼上進行改進完善的,所以在用法上與LevelDB非常的相似。如下,就是簡單的把原來Leveldb信息替換爲Rocksdb,從繼承的角度看,Rocksdb就像是Leveldb的後輩。

RocksDB:

LevelDB:

RocksDB雖然在代碼層面上是在LevelDB原有的代碼上進行開發的,但卻借鑑了Apache HBase的一些好的idea。在雲計算橫行的年代,開口不離Hadoop,RocksDB也開始支持HDFS,允許從HDFS讀取數據。而LevelDB則是一個比較單一的存儲引擎,有點我就是我,除了我依然只有我的感覺。也是因爲LevelDB的單一性,在做具體的應用的時候一般需要對其作進一步擴展。

RocksDB支持一次獲取多個K-V,還支持Key範圍查找。LevelDB只能獲取單個Key

RocksDB除了簡單的Put、Delete操作,還提供了一個Merge操作,說是爲了對多個Put操作進行合併。站在引擎實現者的角度來看,相比其帶來的價值,其實現的成本要昂貴很多。個人覺得有時過於追求完美不見得是好事,據筆者所測(包括測試自己編寫的引擎),性能的瓶頸其實主要在合併上,多一次少一次Put對性能的影響並無大礙。

RocksDB提供一些方便的工具,這些工具包含解析sst文件中的K-V記錄、解析MANIFEST文件的內容等。有了這些工具,就不用再像使用LevelDB那樣,只能在程序中才能知道sst文件K-V的具體信息了。

RocksDB支持多線程合併,而LevelDB是單線程合併的。LSM型的數據結構,最大的性能問題就出現在其合併的時間損耗上,在多CPU的環境下,多線程合併那是LevelDB所無法比擬的。不過據其官網上的介紹,似乎多線程合併還只是針對那些與下一層沒有Key重疊的文件,只是簡單的rename而已,至於在真正數據上的合併方面是否也有用到多線程,就只能看代碼了。

RocksDB增加了合併時過濾器,對一些不再符合條件的K-V進行丟棄,如根據K-V的有效期進行過濾。

壓縮方面RocksDB可採用多種壓縮算法,除了LevelDB用的snappy,還有zlib、bzip2。LevelDB裏面按數據的壓縮率(壓縮後低於75%)判斷是否對數據進行壓縮存儲,而RocksDB典型的做法是Level 0-2不壓縮,最後一層使用zlib,而其它各層採用snappy。

在故障方面,RocksDB支持增量備份和全量備份,允許將已刪除的數據備份到指定的目錄,供後續恢復。

RocksDB支持在單個進程中啓用多個實例,而LevelDB只允許單個實例。

RocksDB支持管道式的Memtable,也就說允許根據需要開闢多個Memtable,以解決Put與Compact速度差異的性能瓶頸問題。在LevelDB裏面因爲只有一個Memtable,如果Memtable滿了卻還來不及持久化,這個時候LevelDB將會減緩Put操作,導致整體性能下降。筆者目前寫的引擎在這方面竟然跟RocksDB不謀而合,這裏偷偷樂一下,呵呵。

看完上面這些介紹,相比LevelDB是不是覺得RocksDB彪悍的不可思議,很多該有的地方都有,該想的都想到了,簡直不像在做引擎庫,更像是在做產品。不過雖然RocksDB在性能上提升了不少,但在文件存儲格式上跟LevelDB還是沒什麼變化的, 稍微有點更新的只是RocksDB對原來LevelDB中sst文件預留下來的MetaBlock進行了具體利用。

個人覺得RocksDB尚未解決的地方:

  1. 依然是完全依賴於MANIFEST,一當該文件丟失,則整個數據庫基本廢掉。
  2. 合併上依然是整個文件載入,一些沒用的Value將被多次的讀入內存,如果這些Value很大的話,那沒必要的內存佔用將是一個可觀的成本。

關於這兩個問題,尤其是後面那個問題,筆者已有相應的解決方案,至於結果如何只等日後實現之後再作解說了。


轉自:http://tech.uc.cn/?p=2592

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章