本文中,開頭我會解釋使用現有模型而非重頭開始此專案的原因。我會闡述一系列選擇鍵值對儲存模型的標準。最後我將對一些廣為人知的鍵值對儲存專案做一個概述,並用這些標準選擇其中一些作為模型。本文將包含:
1. 不重新發明輪子
2. 備選模型和選擇標準
3. 選擇的鍵值對儲存的概述
4. 參考文獻
1. 不重新發明輪子
鍵值對儲存已經被人們唱好至少30年了[1]。最著名的一個專案是DBM,Kenneth Thompson為Unix第七版編寫的最早的資料庫管理器並在1979年釋出[2]。工程師們遇到了和這些資料庫系統相關的一些問題,並選擇或放棄了各種設計和資料結構的想法。對實際生活中的問題進行試驗並從中學習。如果不考慮他們的工作並從頭開始是很愚蠢的,只會重複他們之前所犯過的錯誤。John Gall的系統學中的Gall定理:
任何可以運作的複雜系統都是從可以運作的簡單系統發展而來的。其逆命題同樣是真命題:由無法正常運作的系統設計而來的複雜系統是不可能正常運作的。你必須重頭再來,從一個可運作的簡單系統開始。
這段引述為我的鍵值對儲存專案開發帶來了兩個基礎思想。
1. 使用模型。我需要識別出那些存在了一段時間的鍵值對儲存,甚至更進一步,先前成功的鍵值對儲存的繼任者。這是其可靠設計的證明,並隨著時間在迭代中凝練。這些選擇過的建築的儲存應該作為我現在正在工作的專案的模型。
2.起點小。這個專案的第一版必須小且簡單,這樣它的設計就能簡單的測試並通過。如果需要的話,改進和額外功能必須在後續版本中加入。
2. 待選模型和選擇標準
在對鍵值對儲存和NoSQL資料庫做過一點研究後,我決定將下面的幾個作為進一步選擇的選項:
- DBM
- Berkeley DB
- Kyoto Cabinet
- Memcached and MemcacheDB
- LevelDB
- MongoDB
- Redis
- OpenLDAP
- SQLite
選擇標準如下:
- 我想使用物件導向程式設計來建立鍵值對儲存,所以在設計上,我必須從由面嚮物件語言編寫的專案中汲取靈感。
- 至於底層資料結構,我想要一個存在硬碟上的雜湊表,於是我需要選擇一個提供讀寫資訊到硬碟上的方法的專案。
- 我同樣想讓這個資料儲存能夠有網路接入。
- 我不需要查詢引擎或者方法來訪問結構化的資料.
- 不必完全支援ACID規範。
- 鑑於這個專案是我自己弄的,我想使用那些由小團隊實現的專案模型,理想情況下是一兩個人。
3. 所選鍵值對的概覽
三個獲選的模型是Berkeley DB、Kyoto Cabinet 和LevelDB。Berkeley DB和Kyoto Cabinet作為DBM的繼任者有著相同的歷史。此外,Berkeley DB 和 Kyoto Cabinet 並非“初版”。這表示他倆與其他初次實現的鍵值對儲存專案比較更加可靠。LevelDB則更加現代,並基於LSM樹的資料結構,其對於雜湊表模式來說是無用的。然而其程式碼是我見過最乾淨的。這三個專案都是由一兩個人開發的。下面是他們各自的詳細資訊。
Berkeley DB
Berkeley DB的開發始於1986年,這表示我開始寫這篇文章的時候它已經存在了26年了。Berkeley DB是作為DBM的繼任者而開發的,並實現了一個雜湊表。第一版是由Margo Seltzer [22] 和 Ozan Yigit [23] 在加州大學伯克利分校的時候編寫的。這個專案後來被Oracle獲得,並由其繼續開發。
Berkeley DB最初是由C實現的,並且現在仍然是隻用C。其通過增量過程開發的,就是說在每個主版本增加新的功能。Berkeley DB從一個簡單的鍵值對儲存,進化到管理並行訪問、事務及復原、及同步功能[4]。Berkeley DB的使用非常廣泛,有著數億已部署的拷貝[5],這是可以相信其架構及其可靠的證據。關於其設計的更多資訊可以在“Berkeley DB Programmer’s Reference Guide”[6] 的介紹和“The Architecture of Open Source Applications, Volume 1” [5]的開頭中找到。
Kyoto Cabinet
Kyoto Cabinet在2009年由Mikio Hirabayashi [24] 引進。其現在仍在積極進化中。Kyoto Cabinet是同一個作者的其它鍵值對儲存:Tokyo Cabinet (2007釋出) 和QDBM (2003釋出, 2000開始)的繼任者。QDBM打算作為DBM的高效能繼任者[7]。Kyoto Cabinet尤其有意思,因為它有著DBM的純正血統,並且它的作者在鍵值對儲存方向工作12年了。在浸淫三個鍵值對儲存這麼多年之後,沒有理由懷疑作者有著對結構需求的堅實理解,以及隨之的對效能瓶頸的成因的極強認識。
Kyoto Cabinet是由C++實現的,並實現了一個雜湊表,一個B+樹,以及其他一些深奧的資料結構。其同樣提供了出色的效能[16]。然而,因其內部引數的原因,似乎有些效能問題。的確,很多人報導說只要資料條目的數量保持在某一特定的閾值(正比於桶陣列大小,其由建立資料庫檔案時的引數所確定)以下,效能就很好。一旦超過這個閾值,效能似乎急劇下降[18][19]。Tokyo Cabinet [20] [21] 中也有相同的問題。這表示如果某專案的需求在資料庫使用的時候改變,你可能會遇到嚴重的問題。而我們都知道,軟體中的改變是如此的頻繁。
LevelDB
LevelDB是由Google職員Jeffrey Dean [8] 和 Sanjay Ghemawat [9] 開發,他們為Google傳說中的基礎建設專案MapReduce和BigTable工作。基於Dean和Ghemawat在在Google工作時獲得的大規模問題上的經驗,他們很有可能很瞭解他們正在做的東西。和大多數鍵值對儲存專案相比,LevelDB有一個很有意思的不同點就是它不用雜湊表或者B-樹作為底層資料結構,而是基於一個日誌結構的合併樹[12]。LSM結構據說是為SSD硬碟優化的[13]。你可以在這個部落格High Scalability blog [17]找到成噸的關於LevelDB的資訊。
LevelDB是由C++實現,2011年釋出,並設計作為高階儲存系統的一部分[10]。IndexedDB HTML5 API在Chrome將來版本的實現將使用LevelDB [10] [11]。其效能決定於特定的工作負載,就像作者提供的基準測試中顯示的那樣[14]。然而,Andy Twigg在Acunu的另外一個基於商用SSD的基準測試顯示出,如果資料的條數超過1e6(1百萬),並向1e9(10億)前進的時候,效能將會顯著下降[15]。因此似乎LevelDB似乎並不是重工作負載或像實際後端專案需求那樣的大資料庫最好的選擇。
但這其實並不重要,對於我來說,LevelDB最好的部分不是其效能而是其架構。看它的原始碼和東西組織的方式,那是純粹的美。所有的東西都很清晰、簡單、條理分明。訪問LevelDB的原始碼並把它作為模範是建立出色程式碼的絕好機遇。
那些沒選中的鍵值對儲存是什麼情況?
沒有選擇其他鍵值對儲存的原因並不表示我完全拋棄他們。我會記得他們並可能偶爾使用他們結構中元素。但是,當前專案受到這些鍵值對專案影響不會像已選擇的這些那麼多。
4. 參考文獻
[1] http://blog.knuthaugen.no/2010/03/a-brief-history-of-nosql.html
[2] http://en.wikipedia.org/wiki/Dbm
[3] http://en.wikipedia.org/wiki/Systemantics
[4] http://en.wikipedia.org/wiki/Berkeley_DB#Origin
[5] http://www.aosabook.org/en/bdb.html
[6] http://docs.oracle.com/cd/E17076_02/html/programmer_reference/intro.html
[7] http://fallabs.com/qdbm/
[8] http://research.google.com/people/jeff/
[9] http://research.google.com/pubs/SanjayGhemawat.html
[10] http://google-opensource.blogspot.com/2011/07/leveldb-fast-persistent-key-value-store.html
[11] http://www.w3.org/TR/IndexedDB/
[12] http://www.igvita.com/2012/02/06/sstable-and-log-structured-storage-leveldb/
[13] http://www.acunu.com/2/post/2011/04/log-file-systems-and-ssds-made-for-each-other.html
[14] http://leveldb.googlecode.com/svn/trunk/doc/benchmark.html
[15] http://www.acunu.com/2/post/2011/08/benchmarking-leveldb.html
[16] http://blog.creapptives.com/post/8330476086/leveldb-vs-kyoto-cabinet-my-findings
[17] http://highscalability.com/blog/2011/8/10/leveldb-fast-and-lightweight-keyvalue-database-from-the-auth.html
[18] http://stackoverflow.com/questions/13054852/kyoto-cabinet-berkeley-db-hash-table-size-limitations
[19] https://groups.google.com/forum/#!topic/tokyocabinet-users/Bzp4fLbmcDw/discussion
[20] http://stackoverflow.com/questions/1051847/why-does-tokyo-tyrant-slow-down-exponentially-even-after-adjusting-bnum
[21] https://groups.google.com/forum/#!topic/tokyocabinet-users/1E06DFQM8mI/discussion
[22] http://www.eecs.harvard.edu/margo/
[23] http://www.cse.yorku.ca/~oz/
[24] http://fallabs.com/mikio/profile.html