HBase 架構與工作原理1 - HBase 的數據模型
本文系轉載,如有侵權,請聯系我:[email protected]
一、應用場景
HBase 與 Google 的 BigTable 極為相似,可以說 HBase 就是根據 BigTable 設計的,這一點在 BigTable 論文中也能發現。
在 BigTable 論文中提到了它的應用場景:
BigTable 是一個分布式的結構化數據存儲系統,它被設計用來處理海量數據:通常是分布在數千臺普通服務器上的 PB 級的數據。
Google 的很多項目使用 Bigtable 存儲數據,包括 Web 索引、Google Earth、Google Finance。這些應用對 Bigtable 提出的要求差異非常大,無論是在數據量上(從 URL 到網頁到衛星圖像)還是在響應速度上(從後 端的批量處理到實時數據服務)。
Bigtable 已經在超過 60 個 Google 的產品和項目上得到了應用,包括 Google Analytics、Google Finance、 Orkut、Personalized Search、Writely 和 Google Earth。
以上應用場景的一個典型特點就是會不斷的插入新的數據,而不怎麽修改,比如Web 索引、Google Earth。而同時呢,也可能需要保存一定的歷史數據用以查看或分析,比如網頁快照、Google Analytics、或者聯想到如今的大數據中,根據您以往的行為來預測您的行為與喜好等。另外它存儲的屬性可能會很多且不固定,比如一個網頁的數據,除了它的內容外,可能還需要存儲它相關的外鏈、關鍵字、錨點、標題、圖片等。
那麽根據這些應用的需求,對 BigTable 中的數據總結有以下特點:
- 數據量大
- 屬性不固定
- 插入多,但不存在頻繁的修改
- 存在歷史版本數據
二、Table 組成元素
在 HBase 中,數據存儲在具有行和列的表中,表的每行包含一個或多個列族,每個列族則可能包含一個或多個列,而行與列的交叉點則被稱為單元格,用來存放數據的值。
表(Table)
Table 是在創建表時的 schema 聲明定義的,其一旦創建便不可修改。
行(Row)
與傳統關系系數據庫類似卻又不太相同,HBase 中的行具有如下特點:
- 行由一個或多個列族組成,每個列族包含一個或多個列,列可以動態添加;
- 每個行都包含一個行鍵(Rowkey),類似於關系型數據庫中的主鍵。
- 行鍵是不可分割的字節數組,Table 中的行按照行鍵的字典序由低到高有序排列。
- 每行可以存儲多個歷史版本,默認讀取的為最新的版本;
列族(Column Family)
列族是一個或多個列的集合,列可以動態增減,但是列族則需要在創建或修改表時提前定義。同一個列族下的所有列使用相同的前綴來標識其屬於哪一個列族,比如列courses:history
和courses:math
都是列族courses
的成員。
在物理存儲上,一個列族下的所有成員在文件系統上是存儲在一起的,這個原理對於之後的優化有著重要的意義。
單元格(Cells)
單元格是行與列的交叉點,同時因為版本的存在,所以它類似於一個3維元祖 {row, column, version},同行鍵一樣,單元格中的內容也是不可分割的字節數組。
三、示例
以稍微修改過的 BigTable 論文中的 Webtable 為例:有一個名為 WebTable 的表格,其中包含兩行(com.cnn.www 和 com.example.www)和三個名為 contents、anchor 和 people 的列族。對於第一行(com.cnn.www),anchor 包含兩列(anchor:cssnsi.com,anchor:my.look.ca),contants 包含一列(contents:html)。同時,row key 為 com.cnn.www 的行保存了 5 個版本(5 個歷史數據),row key 為 com.example.www 的行則只保存了 1 個版本。contents 列族中,html 列限定符中包含指定網站的整個 HTML 內容。anchor 列族中,每個限定符都包含鏈接到該行所代表的站點的外部站點,以及它在鏈接錨點(anchor)中使用的文本。people 列族中則保存與該網站相關的人員。
那麽根據這個示例,可以得到如下的邏輯視圖與物理視圖。
邏輯視圖
Row Key | Time Stamp | ColumnFamily contents | ColumnFamily anchor | ColumnFamily people |
---|---|---|---|---|
“com.cnn.www” | t9 | anchor:cnnsi.com = “CNN” | ||
“com.cnn.www” | t8 | anchor:my.look.ca = “CNN.com” | ||
“com.cnn.www” | t6 | contents:html = “<html>…?” | ||
“com.cnn.www” | t5 | contents:html = “<html>…?” | ||
“com.cnn.www” | t3 | contents:html = “<html>…?” | ||
“com.example.www” | t5 | contents:html = “<html>…?” | people:author = “John Doe” |
與傳統的關系型數據庫不同的是,此表中為空的單元格(Cell)在實際中並不會占用空間或者說事實上並不存在,這正是 HBase “稀疏”的原因。使用表格只是查看 HBase 數據的一種方式,同樣也可以轉換成 JSON 格式:
{
"com.cnn.www": {
contents: {
t6: contents:html: "<html>..."
t5: contents:html: "<html>..."
t3: contents:html: "<html>..."
}
anchor: {
t9: anchor:cnnsi.com = "CNN"
t8: anchor:my.look.ca = "CNN.com"
}
people: {}
}
"com.example.www": {
contents: {
t5: contents:html: "<html>..."
}
anchor: {}
people: {
t5: people:author: "John Doe"
}
}
}
物理視圖
HBase 的數據按照列族(cloumn family)物理存儲。也即是說不同列族下的數據被分開存放,您可以隨時將新的列限定符(column_family:column_qualifier)添加到現有的列族。對應上面的示例,它的物理存儲如下:
列族 anchor:
Row Key | Time Stamp | Column Family anchor |
---|---|---|
“com.cnn.www” | t9 | anchor:cnnsi.com = “CNN” |
“com.cnn.www” | t8 | anchor:my.look.ca = “CNN.com” |
列族 contents:
Row Key | Time Stamp | Column Family contents |
---|---|---|
“com.cnn.www” | t6 | contents:html = “<html>…?” |
“com.cnn.www” | t5 | contents:html = “<html>…?” |
“com.cnn.www” | t3 | contents:html = “<html>…?” |
列族 people:
Row Key | Time Stamp | Column Family people |
---|---|---|
“com.example.www” | t5 | people:author = “John Doe” |
這樣的物理視圖有 3 個特點:
- 概念視圖中的空的單元格不會被存儲;
- 通過 Rowkey、時間戳、列族與限定符可以定位到一條數據;
- 如果未指定時間戳,將返回最新的數據。比如 get(RowKey=”com.cnn.www”, column_family:column_qualifier=”contents:html”),將返回 t6 時間的值。
參考鏈接
- Google-Bigtable 中文版
- Apache HBase ™ Reference Guide # DataModel
- understanding HBase and BigTable
- HBase 官方文檔中文版
HBase 架構與工作原理1 - HBase 的數據模型