您的位置:首頁>正文

NoSQL的復興和模型簡化的力量(上篇)

在介紹 NoSQL 之前, 我想提兩個公司, 一個是Google, 另一個是Amazon。

Google

Google 應該是第一個將分散式存儲技術應用到大規模生產環境的公司, 同時也是在分散式系統上積累最深的公司, 可以說目前工業界的分散式系統的工程實踐及思想大都來源於 Google。 比如 2003 年的 GFS 開創了分散式檔案系統, 2006 年的 Bigtable 論文開創了分散式鍵值系統, 直接催生的就是 Hadoop 的生態;至於 2012 年發表論文的Spanner和F1更是一個指明未來關係型數據庫發展方向的里程碑式的項目, 這個我們後續會說。

Amazon

另一個公司是 Amazon。 2007 年發表的Dynamo的論文嘗試引入了最終一致性的概念, WRN 的模型及向量時鐘的應用,

同時將一致性 HASH、merkle tree 等當時一些很新潮的技術整合起來, 正式標誌著 NoSQL 的誕生——對後來業界的影響也是很大, 包括後來的 Cassandra、RiakDB、Voldemort 等資料庫都是基於 Dynamo 的設計發展起來的。

新思潮

另外這個時期(2006 年前後持續至今)一個比較重要的思潮就是資料庫(持久化)和緩存開始有明確的分離——我覺得這個趨勢是從 memcached 開始的。

隨著業務的併發越來越高, 對於低延遲的要求也越來越高;另外一個原因是隨著記憶體越來越便宜, 基於記憶體的存儲方案漸漸開始普及。 當然記憶體緩存方案也經歷了一個從單機到分散式的過程, 但是這個過程相比關係型數據庫的進化要快得多。

這是因為 NoSQL 的另外一個重要的標誌——資料模型的變化——大多 NoSQL 都拋棄了關係模型, 選擇更簡單的鍵值或者文檔類型進行存儲。 資料結構和查詢介面都相對簡單, 沒有了SQL 的包袱, 實現的難度會降低很多。

另外 NoSQL 的設計幾乎都選擇犧牲掉複雜 SQL 的支援及 ACID 事務換取彈性擴展能力, 也是從當時互聯網的實際情況出發:業務模型簡單、爆發性增長帶來的海量併發及資料總量爆炸、歷史包袱小、工程師強悍,

等。 其中最重要的還是業務模型相對簡單。

嵌入式存儲引擎

在開始介紹具體的開源的完整方案前, 我想介紹一下嵌入式存儲引擎們。

隨著 NoSQL 的發展, 不僅僅緩存和持久化存儲開始細分, 再往後的存儲引擎也開始分化並走上前臺。 之前很難想像一個存儲引擎獨立於資料庫直接對外提供服務, 就像你不會直接拿著 InnoDB 或者 MyISAM甚至一個 B-tree 出來用一樣(當然, bdb 這樣鼎鼎大名的除外)。 人們基於這些開源的存儲引擎進行進一步的封裝, 比如加上網路通訊協定層、加上複製機制等等, 一步步構建出完整的風格各異的 NoSQL 產品。

這裡我挑選幾個比較著名存儲引擎介紹一下。

TC

我最早接觸的是Tokyo Cabinet(TC)。 TC 相信很多人也都聽說過, TC 是由日本最大的社交網站 Mixi 開發並開源的一個混合 Key-Value 存儲引擎, 其中包括 HASH Table 和 B+ Tree 的實現。 但是這個引擎的一個缺陷是隨著資料量的膨脹, 性能的下降會非常明顯, 而且現在也基本不怎麼維護了, 所以入坑請慎重。 於 TC 配合使用的Tokyo Tyrant(TT)是一個網路庫, 為 TC 提供網路的介面使其變成一個資料庫服務, TT + TC 應該是比較早的 NoSQL 的一個嘗試。

LevelDB

在 2011 年, Google 開源了 Bigtable 的底層存儲擎:LevelDB。 LevelDB 是一個使用 C++ 開發的嵌入式的 Key-Value 存儲引擎, 資料結構採用了 LSM-Tree, 具體 LSM-Tree 的演算法分析可以很容易在網上搜索到, 我就不贅述了。 其特點是, 對於寫入極其友好, LSM 的設計避免了大量的隨機寫入;對於特定的讀也能達到不錯的性能(熱資料在記憶體中);另外 LSM-Tree 和 B-tree 一樣是支持有序 Scan 的;而且 LevelDB 是出自 Jeff Dean 之手,

他的事蹟做分散式系統的朋友一定都知道, 不知道的可以去 Google 搜一下。

LevelDB 擁有極好的寫性能, 執行緒安全, BaTCh Write 和 Snapshot 等特性, 使其很容易的在上層構建 MVCC 系統或者事務模型, 對於資料庫來說非常重要。

另外值得一說的是,Facebook 維護了一個活躍的 LevelDB 的分支,名為 RocksDB。RocksDB 在 LevelDB 上做了很多的改進,比如多執行緒 Compactor、分層自訂壓縮、多 MemTable 等。另外 RocksDB 對外暴露了很多 Configration ,可以根據不同業務的形態進行調優;同時 Facebook 在內部正在用 RocksDB 來實現一個全新的 MySQL 存儲引擎:MyRocks,值得關注。RocksDB 的社區回應速度很快也很友好,實際上 PingCAP 也是 RocksDB 的社區貢獻者。我建議新的項目如果在 LevelDB 和 RocksDB 之間糾結的話,請果斷選擇 RocksDB。

B-tree 家族

當然,除了 LSM-Tree 外,B-tree的家族也還是有很多不錯的引擎。首先大多數傳統的單機資料庫的存儲引擎都選擇了B+Tree,B+Tree 對磁片的讀比較友好,協力廠商存儲引擎比較著名的純 B+Tree 實現是LMDB。首先 LMDB 選擇在記憶體映射檔 (mmap) 實現 B+Tree,同時使用了 Copy-On-Write 實現了 MVCC 實現併發事務無鎖讀的能力,對於高併發讀的場景比較友好;同時因為使用的是 mmap 所以擁有跨進程讀取的能力。因為我並沒有在生產環境中使用過 LMDB ,所以並不能給出 LMDB 的一些缺陷,見諒。

另外值得一說的是,Facebook 維護了一個活躍的 LevelDB 的分支,名為 RocksDB。RocksDB 在 LevelDB 上做了很多的改進,比如多執行緒 Compactor、分層自訂壓縮、多 MemTable 等。另外 RocksDB 對外暴露了很多 Configration ,可以根據不同業務的形態進行調優;同時 Facebook 在內部正在用 RocksDB 來實現一個全新的 MySQL 存儲引擎:MyRocks,值得關注。RocksDB 的社區回應速度很快也很友好,實際上 PingCAP 也是 RocksDB 的社區貢獻者。我建議新的項目如果在 LevelDB 和 RocksDB 之間糾結的話,請果斷選擇 RocksDB。

B-tree 家族

當然,除了 LSM-Tree 外,B-tree的家族也還是有很多不錯的引擎。首先大多數傳統的單機資料庫的存儲引擎都選擇了B+Tree,B+Tree 對磁片的讀比較友好,協力廠商存儲引擎比較著名的純 B+Tree 實現是LMDB。首先 LMDB 選擇在記憶體映射檔 (mmap) 實現 B+Tree,同時使用了 Copy-On-Write 實現了 MVCC 實現併發事務無鎖讀的能力,對於高併發讀的場景比較友好;同時因為使用的是 mmap 所以擁有跨進程讀取的能力。因為我並沒有在生產環境中使用過 LMDB ,所以並不能給出 LMDB 的一些缺陷,見諒。

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示