理解HBase(一個開源的Google的BigTable實際應用)最大的困難是HBase的數據結構概念到底是什麼?首先HBase不一樣於通常的關係數據庫,它是一個適合於非結構化數據存儲的數據庫.另外一個不一樣的是HBase基於列的而不是基於行的模式.html
Google's BigTable論文 清楚地解釋了什麼是BigTable:
Bigtable是一個疏鬆的分佈式的持久的多維排序的map,這個map被行鍵,列鍵,和時間戳索引.每個值都是連續的byte數組.(A Bigtable is a sparse, distributed, persistent multidimensional sorted map. The map is indexed by a row key, column key, and a timestamp; each value in the map is an uninterpreted array of bytes.)mysql
Hadoop wiki的HBase架構 頁面提到:
HBase使用和Bigtable很是相同的數據模型.用戶存儲數據行在一個表裏.一個數據行擁有一個可選擇的鍵和任意數量的列.表是疏鬆的存儲的,所以 用戶能夠給行定義各類不一樣的列.(HBase uses a data model very similar to that of Bigtable. Users store data rows in labelled tables. A data row has a sortable key and an arbitrary number of columns. The table is stored sparsely, so that rows in the same table can have crazily-varying columns, if the user likes.)算法
1、架構思路sql
Hbase是基於Hadoop的項目,因此通常狀況下咱們使用的直接就是HDFS文件系統,這裏咱們不深談HDFS如何構造其分佈式的文件系統,只須要知 道雖然Hbase中有多個RegionServer的概念,並不意味着數據是持久化在RegionServer上的,事實上,RegionServer是 調度者,管理Regions,可是數據是持久化在HDFS上的。明確這一點,在後面的討論中,咱們直接把文件系統抽象爲HDFS,再也不深究。數據庫
Hbase是一個分佈式的數據庫,使用Zookeeper來管理集羣。在架構層面上分爲Master(Zookeeper中的leader)和多個RegionServer,基本架構如圖:apache
在Hbase的概念中,RegionServer對應於集羣中的一個節點,而一個RegionServer負責管理多個Region。一個Region代 表一張表的一部分數據,因此在Hbase中的一張表可能會須要不少個Region來存儲其數據,可是每一個Region中的數據並非雜亂無章 的,Hbase在管理Region的時候會給每一個Region定義一個Rowkey的範圍,落在特定範圍內的數據將交給特定的Region,從而將負載分 攤到多個節點上,充分利用分佈式的優勢。另外,Hbase會自動的調節Region處在的位置,若是一個RegionServer變得Hot(大量的請求 落在這個Server管理的Region上),Hbase就會把Region移動到相對空閒的節點,依次保證集羣環境被充分利用。數組
2、存儲模型網絡
有了架構層面的保證,接下來的事情就只是關注於數據的具體存儲了。這裏就是每一個Region所承擔的工做了。咱們知道一個Region表明的是一張 Hbase表中特定Rowkey範圍內的數據,而Hbase是面向列存儲的數據庫,因此在一個Region中,有多個文件來存儲這些列。Hbase中數據 列是由列簇來組織的,因此每個列簇都會有對應的一個數據結構,Hbase將列簇的存儲數據結構抽象爲Store,一個Store表明一個列簇。數據結構
因此在這裏也能夠看出爲何在咱們查詢的時候要儘可能減小不須要的列,而常常一塊兒查詢的列要組織到一個列簇裏:由於要須要查詢的列簇越多,意味着要掃描越多的Store文件,這就須要越多的時間。架構
咱們來深刻Store中存儲數據的方式。Hbase的實現是用了一種LSM 樹的結構!
LSM樹是由B+樹改進而來,因此咱們首先來簡單的看看B+樹。
這是一顆簡單的B+樹,含義不言而喻,這裏很少分析,可是這種數據結構並不適合Hbase中的應用場景。這樣的數據結構在內存中效率是很高的,可是 Hbase中數據是存儲在文件中的,若是按照這樣的結構來存儲,意味着咱們每一次插入數據都要由一級索引找到文件再在文件中間做操做來保證數據的有序性, 這無疑是效率低下的。因此Hbase採用的是LSM樹的結構,這種結構的關鍵是,每一次的插入操做都會先進入MemStore(內存緩衝區),當 MemStore達到上限的時候,Hbase會將內存中的數據輸出爲有序的StoreFile文件數據(根據Rowkey、版本、列名排序,這裏已經和列 簇無關了由於Store裏都屬於同一個列簇)。這樣會在Store中造成不少個小的StoreFile,當這些小的File數量達到一個閥值的時 候,Hbase會用一個線程來把這些小File合併成一個大的File。這樣,Hbase就把效率低下的文件中的插入、移動操做轉變成了單純的文件輸出、 合併操做。
由上可知,在Hbase底層的Store數據結構中,每一個StoreFile內的數據是有序的,可是StoreFile之間不必定是有序的,Store只 須要管理StoreFile的索引就能夠了。這裏也能夠看出爲何指定版本和Rowkey能夠增強查詢的效率,由於指定版本和Rowkey的查詢能夠利用 StoreFile的索引跳過一些確定不包含目標數據的數據。
HBase | Cassandra | |
---|---|---|
語言 | Java | Java |
出發點 | BigTable | BigTable and Dynamo |
License | Apache | Apache |
Protocol | HTTP/REST (also Thrift) | Custom, binary (Thrift) |
數據分佈 | 表劃分爲多個region存在不一樣region server上 | 改進的一致性哈希(虛擬節點) |
存儲目標 | 大文件 | 小文件 |
一致性 | 強一致性 | 最終一致性,Quorum NRW策略 |
架構 | master/slave | p2p |
高可用性 | NameNode是HDFS的單點故障點 | P2P和去中心化設計,不會出現單點故障 |
伸縮性 | Region Server擴容,經過將自身發佈到Master,Master均勻分佈Region | 擴容需在Hash Ring上多個節點間調整數據分佈 |
讀寫性能 | 數據讀寫定位可能要經過最多6次的網絡RPC,性能較低。 | 數據讀寫定位很是快 |
數據衝突處理 | 樂觀併發控制(optimistic concurrency control) | 向量時鐘 |
臨時故障處理 | Region Server宕機,重作HLog | 數據回傳機制:某節點宕機,hash到該節點的新數據自動路由到下一節點作 hinted handoff,源節點恢復後,推送回源節點。 |
永久故障恢復 | Region Server恢復,master從新給其分配region | Merkle 哈希樹,經過Gossip協議同步Merkle Tree,維護集羣節點間的數據一致性 |
成員通訊及錯誤檢測 | Zookeeper | 基於Gossip |
CAP | 1,強一致性,0數據丟失。2,可用性低。3,擴容方便。 | 1,弱一致性,數據可能丟失。2,可用性高。3,擴容方便。 |