隨着信息技術的高速發展,數據存儲量和流量呈現爆炸式增加。目前百度統計日 PV(日點擊量)已超過 75 億次,中國網民在百度上進行50 億次的搜索請求,百度貼吧日 PV 十億,天天發帖三千多萬;百度知道爲中國網民解決了2.3億個問題,日均 PV4.17 億。百度的數據總量已接近幾千個PB,天天要響應幾百萬次的搜索請求,天天處理 100PB 數據。c++
如此龐大的數據量給數據儲存系統帶來了巨大挑戰,單機PC基本沒法處理如此大量的PB級數據,分機存儲成爲大勢所趨,因而自上世紀便提出的分佈式系統理論成爲當下最優解,Level DB也在近年應運而生。算法
Level DB 是一個持久性數據存儲量能達到 Billion 級別的很是高效的鍵值型C++函數庫,於2011年由Google發佈。在其底層實現上使用了 LSM-tree(Log Structured Merge Tree)算法,以犧牲隨機讀換取順序寫,從而實現了數據的高效持久化存儲。數據庫
LSM-tree 的思想其實很是易於理解,就是將對數據的大量修改以增量的形式保持在內存中,當數據量達到指定的大小限制後將這些修改操做批量寫入磁盤,即順序寫;讀取時須要合併磁盤中的歷史數據和內存中最近的修改操做。LSM 樹的優點在於有效地規避了磁盤隨機寫入問題,但讀取時可能須要訪問較多的磁盤文件。數組
Level DB 經過將數據更多地緩存在內存中,提升數據的命中率,避免讀數據時過多的訪問磁盤,進而提升讀數據的總體效率。它有以下特色:緩存
1. 基於 Key/Value 的持久化存儲系統,與 Redis 這種基於 Key/Value 的內存型存儲系統不一樣之處在於,Level DB 將大部分的數據存儲到磁盤介質上,這樣就不會有太多的內存開銷,從而提升了效率。架構
2. 鍵值是任意字節的數組。數據經過鍵存儲排序。調用者提供一個定製的比較重載的排序順序。先後迭代是以數據爲支撐的。app
3. 可以有序的存儲記錄的鍵值,在系統中相鄰的鍵值是按照一個比較函數,依次有序的存儲在介質中,這個比較方法能夠自行定義,Levle DB 根據這個比較方法依次來保存記錄。分佈式
4. 經過一個虛擬接口,外部活動(如文件系統操做等)就能傳送,用戶就能定製操做系統的相互做用。Level DB 不只提供數據讀取、寫入以及刪除等簡單的接口,並且也提供批量存取服務。函數
5. 支持數據快照(可理解爲只讀權限的數據庫。Snapshot 不但有爲報表提供靜態的視圖服務的優勢,並且當與數據庫鏡像結合使用時提供讀寫分離功能,而最重要的一點能夠利用數據庫快照來快速恢復數據庫。)功能,經過創建瞬間的快照,可以使寫操做不會影響到讀操做,可以在讀操做過程當中始終看到一致的數據,避免髒數據等不一致性問題。性能
6. 支持數據壓縮功能,經過使用 Snappy(Snappy 是一個以 BSD 協議開源的開發包,提供數據壓縮和數據解壓功能。用來壓縮較爲大量級的數據,其穩定性和健壯性較好。)壓縮庫自動壓縮數據。這對不只能夠增快讀/寫效率並且有助於減少存儲空間。
7. 只是一套 c++程序庫,底層提供了抽象接口,容許用戶定製,不是 SQL數據庫,沒有數據關係模型,單機系統沒有 client-server。
集羣化 Level DB 存儲系統解決方案在很大程度上突破了傳統意義上附屬於主機的存儲設備只能存放數據的範疇,而現代的存儲系統以大量廉價的普通計算機爲基礎平臺,配合複雜的管理軟件來存放海量數據,並能對這些大量級的數據進行管理使其可靠、高效、合理性管理。集羣化 Level DB 在大量廉價物理機上,基於 Level DB 核提供基本的數據存儲服務,採起各類策略保證數據的完整性、系統的可靠性,使其存儲、讀寫等服務有更高的效率。
實際上 Level DB 就是一個數據存儲系統和基於該系統的接口規範。它的存儲介質是文件和內存,經過拍照咱們能看到這樣的情景:
Level DB 總體架構圖
如圖所示,系統的總體靜態架構由六部分組成:內存中的 Mem Table 和Immutable Mem Table;磁盤的 Current 文件、Manifest 文件、Log 文件和 SSTable(Sorted Strings Table)幾種主要文件。
Level DB 中的 Mem Table 文件當須要寫入一條記錄時,系統會先向 log 文件中插入該記錄,當成功插入到 log 文件後,再去將該記錄寫入到 Mem Table 中,成功寫入到 Mem Table 後纔算完成一次基本寫入成功。而說 Level DB 寫入速度極快的首要緣由,也正是因爲它的一次寫入數據只涉及到一次內存寫入和磁盤寫入的操做。
爲儘可能避免數據丟失,Level DB採用先將數據寫入到 Log 文件,而後釋放到系統 Memtable,一旦宕機也能夠從 Log 將數據恢復到 Memtable。
在插入數據時,Memtable 達到必定大小就會將內容導出到外部文件,Levle DB 會從新生成 Log 文件和 Mem Table,舊的 Memtable 就變爲了 Immutable Memtable。從字面上咱們就可以看出,Mem Table 的內容 Mem Table 的內容只能進行讀操做。新數據會被記錄到新產生的 Log 文件和 Memtable 中,同時後臺將 Immutable Memtable 到數據保存到磁盤。內存中的記錄不停釋放到介質中並進行 Compaction 操做後造成了 SSTable,而 SSTable 是由一類層級構成的文件,第一層爲 Level 0,第二層爲 Level 1,直到第 12 層爲止。
SSTable 中的每一個文件屬於哪一層的層級,並且順序的存儲着記錄的 Key值,事實上在文件中 key 值越小的記錄排列的順序越靠前。因此必然有文件中的最小 key 值與最大 key 值,固然這些信息也一樣是極爲重要的,Level DB 系統中的Manifest 文件負責記載 SSTable 各個文件的管理信息,例如層級信息,文件名稱,最小 key 值與最大 key 值等信息。下圖是 Manifest存儲信息的示意圖:
Manifest示意圖
如圖所示,看到兩個文件,即 Level 0 的兩個文件,都記在了 key 範圍,a1 的 key 範圍是「aaa」到「xxx」,文件 a2 的 key 範圍是「bbb」到「yyy」,二者 key部分就重疊了。
Current 文件只負責記錄當前系統使用的 Manifest 文件名。上面咱們知道了系統的運行會不斷的進行 Compaction 操做,SSTable 也隨之改變,而 Manifest文件也會隨之發生改變,一樣會產生一個新的 Manifest 文件來記錄這些信息,而Current 文件則是記錄當前系統所正在使用究竟是哪一個 Manifest 文件。
以上爲Level DB的整體架構,如下展現Level DB讀寫數據流程圖:
Level DB 讀取數據流程圖
Level DB 寫入數據流程圖
根據 Google 給出的測試報告,Level DB 具備很高的寫入速度,其隨機寫性能能夠達到40萬條記錄每秒,而隨機讀性能也達到 6 萬條記錄每秒。
總而言之,Level DB 是一個很是高效的海量鍵值存儲引擎、一個用 C++實現的類庫、一個單機持久化存儲系統,普遍應用於各類須要處理龐大數據量的企業中,也十分受到分佈式系統研究領域學者們的青睞,近年來在雲計算、集羣化數據等領域表現活躍。