下面性能測試對比來自LevelDB官方,由 NoSQLFan 進行翻譯整理。從結果上看,這不像某些田忌賽馬式的性能對比,總體來說還是比較客觀全面。通過多種場景下的不同性能測試結果的對比,我們也能對這三個數據庫分別擅長和適用的場合有所了解。同時對其性能調優的方法理解也有一定的幫助。

原文鏈接:leveldb.googlecode.com

下面是對LevelDB、TreeDBSQLite3 這幾個數據庫的性能對比測試,分別使用了LevelDB (revision 39) SQLite3 (version 3.7.6.3) 及 Kyoto Cabinet’s (version 1.2.67)這三個版本的數據庫。

測試機器配置:six-core Intel(R) Xeon(R) CPU X5650 @ 2.67GHz, with 12288 KB of total L3 cache and 12 GB of DDR3 RAM at 1333 MHz

文件系統:測試腳本分別跑在兩臺機器上,其文件系統一臺為ext3(磁盤為 SATA Hitachi HDS721050CLA362),一臺為ext4(配備磁盤 SATA Samsung HD502HJ)

性能測試源碼:

基本測試

基本測試的條件如下:

  • 每個數據庫使用4GB內存
  • 數據庫都處于異步寫模式(LevelDB’s sync option, TreeDB’s OAUTOSYNC option, SQLite3’s synchronous options 都關閉),也就是說寫操作不用等數據真正寫到磁盤上才返回。
  • Key 的長度為16字節
  • Value 的長度為100字節 (這個長度才能讓數據庫的壓縮算法能夠起作用,將數據壓縮至50%大小左右)
  • 順序讀寫時Key值遞增變化
  • 隨機讀時生成隨機的Key值

測試結果:



結果顯示,在順序讀寫和隨機寫上,LevelDB 在性能上都遙遙領先,在隨機讀上面 Kyoto Cabinet 引擎稍快一些。

在幾種不同策略下進行寫操作測試

A. Values 為長數據(數據長度為100,000字節)

LevelDB在Value較長時性能比較低,這是由于LevelDB對每一次寫操作都會至少進行兩次寫動作,一次是寫數據文件,另一次是寫日志文件。這里慢的主要原因是LevelDB在進行這些操作時對值進行了過多的Copy。

B. 批量寫操作

一次寫操作寫1000條100字節的數據,由于TreeDB不支持批量寫入,故未對其進行對比測試

上面結果是由于LevelDB數據的組織方式,導致順序寫和隨機寫在性能上都變化不大。

C. 同步進行寫操作

  • 對 LevelDB, 設置 WriteOptions.sync = true.
  • 對 TreeDB, 將 TreeDB’s OAUTOSYNC 選項開啟.
  • 對 SQLite3, 設置 “PRAGMA synchronous = FULL”.

如果你看一下ext4文件系統下的測試數據,你會發現ext3和ext4在表現上非常不同。

D. 無壓縮的寫操作

LevelDB 和 TreeDB 都支持相應的數據壓縮算法(LevelDB 使用的是 Snappy , TreeDB 使用的是 LZO),由于SQLite不支持壓縮,所以這里的測試數據只是從上面的基本測試結果copy過來的。

LevelDB開啟壓縮比不開啟壓縮效率更高,而TreeDB則相反,這可能是由于TreeDB采用的壓縮算法(LZO)與LevelDB采用的壓縮算法(Snappy)相比計算代價更高。

E. 使用更大內存

將每個獨立庫的內存增大到128MB,對LevelDB來說,其中120MB用來做 write buffer,另外8MB用來做 cache(原來是2MB的 write buffer 和2MB的cache),對SQLite來說,我們不改變其page size,還是保持為1kb,但是我們增大其page數量從4k增加到128k,對TreeDB來說,我們同樣不改變其page大小,也只是增大其cache,從4MB增大到128MB。

SQLite 在采用了大內存后性能變化并不大,而 LevelDB 和 TreeDB 的隨機寫性能卻有顯著提高。LevelDB 在增大內存后性能提升的原因是其write buffer 更大,從而減少了創建的sorted file的次數。減少了磁盤IO。而 TreeDB 的性能提升原因是由于其數據庫的更大部分被映射到內存中了。

在幾種不同策略下進行讀操作測試

A. 大的Cache空間

我們分配128MB給每個數據庫,對LevelDB來說,我們分配8MB給 write buffer,120MB給cache,對另外兩個數據庫,由于它們不支持區分 write buffer 和cache,所以統一將 cache size設置成128MB。

從結果可以看到,增大Cache在數據庫讀性能上都有所提升,其中最為顯著的是TreeDB,其隨機讀性能大幅提升。主要是由于有足夠的內存使得其所有讀操作都幾乎是在內存中進行。

B. 無壓縮的讀操作

下面結果是我們對預先無壓縮狀態寫入的100萬條key為16字節、value為100字節的數據后進行的讀性能測試。同樣的 SQLite 由于不支持壓縮,所以下面數據是直接從其基本測試上copy過來的。

結果可以看到,取消壓縮對讀取性能提升不是特別大,當然,如果你的數據都在內存中的話,執行解壓操作也不會對性能造成太大影響。