HBase數據模型剖析

出處:http://wuyudong.com/1987.htmlhtml

HBase 進行數據建模的方式和你熟悉的關係型數據庫有些不一樣。關係型數據庫圍繞表、列和數據類型——數據的形態使用嚴格的規則。遵照這些嚴格規則的數據稱爲結構化數據。HBase 設計上沒有嚴格形態的數據。數據記錄可能包含不一致的列、不肯定大小等。這種數據稱爲半結構化數據(semistructured data)。java

在邏輯模型裏針對結構化或半結構化數據的導向影響了數據系統物理模型的設計。關係型數據庫假定表中的記錄都是結構化的和高度有規律的。所以,在物理實現時,利用這一點相應優化硬盤上的存放格式和內存裏的結構。一樣,HBase 也會利用所存儲數據是半結構化的特色。隨着系統發展,物理模型上的不一樣也會影響邏輯模型。由於這種雙向緊密的聯繫,優化數據系統必須深刻理解邏輯模型和物理模型。數據庫

除了面向半結構化數據的特色外,HBase 還有另一個重要考慮因素——可擴展性。在半結構化邏輯模型裏數據構成是鬆耦合的,這一點有利於物理分散存放。HBase 的物理模型設計上適合於物理分散存放,這一點也影響了邏輯模型。此外,這種物理模型設計迫使HBase 放棄了一些關係型數據庫具備的特性。特別是,HBase 不能實施關係約束(constraint)而且不支持多行事務(multirow transaction)。這種關係影響了下面幾個主題。編程

邏輯模型:有序映射的映射集合ubuntu

HBase 中使用的邏輯數據模型有許多有效的描述。圖2-6 把這個模型解釋爲鍵值數據庫。咱們考慮的一種描述是有序映射的映射(sorted map of maps)。你大概熟悉編程語言裏的映射集合或者字典結構。能夠把HBase 看作這種結構的無限的、實體化的、嵌套的版本。設計模式

咱們先來思考映射的映射這個概念。HBase 使用座標系統來識別單元裏的數據:[行鍵,列族,列限定符,時間版本]。例如,從users 表裏取出Mark 的記錄編程語言

20160318162026

理解映射的映射的概念時,把這些座標從裏往外看。你能夠想象,開始以時間版本爲鍵、數據爲值創建單元映射,往上一層以列限定符爲鍵、單元映射爲值創建列族映射,最後以行鍵爲鍵列族映射爲值創建表映射。這個龐然大物用Java 描述是這樣的:Map<RowKey, Map<ColumnFamily, Map<ColumnQualifier, Map<Version,Data>>>>。不算漂亮,可是簡單易懂。工具

注意咱們說映射的映射是有序的。上述例子只顯示了一條記錄,即便如此也能夠看到順序。注意password 單元有兩個時間版本。最新時間版本排在稍晚時間版本以前。HBase 按照時間戳降序排列各時間版本,因此最新數據老是在最前面。這種物理設計明顯致使能夠快速訪問最新時間版本。其餘的映射鍵按照升序排列。如今的例子看不到這一點,讓咱們插入幾行記錄看看是什麼樣子:性能

wu@ubuntu:~/opt/twitbase$ java -cp target/twitbase-1.0.0.jar HBaseIA.TwitBase.UsersTool add HMS_Surprise "Patrick O'Brian" aubrey@sea.com abc123優化

Successfully added user <User: HMS_Surprise, Patrick O'Brian, aubrey@sea.com, 0>

wu@ubuntu:~/opt/twitbase$ java -cp target/twitbase-1.0.0.jar HBaseIA.TwitBase.UsersTool add GrandpaD "Fyodor Dostoyevsky" fyodor@brothers.net abc123

Successfully added user <User: GrandpaD, Fyodor Dostoyevsky, fyodor@brothers.net, 0>

wu@ubuntu:~/opt/twitbase$ java -cp target/twitbase-1.0.0.jar HBaseIA.TwitBase.UsersTool add SirDoyle "Sir Arthur Conan Doyle" art@TheQueensMen.co.uk abc123

Successfully added user <User: SirDoyle, Sir Arthur Conan Doyle, art@TheQueensMen.co.uk, 0>

如今再次列出Users 表的內容,能夠看到:

wu@ubuntu:~/opt/twitbase$ java -cp target/twitbase-1.0.0.jar HBaseIA.TwitBase.UsersTool list

16/03/18 01:31:51 INFO TwitBase.UsersTool: Found 4 users.
<User: GrandpaD, Fyodor Dostoyevsky, fyodor@brothers.net, 0>
<User: HMS_Surprise, Patrick O'Brian, aubrey@sea.com, 0>
<User: SirDoyle, Sir Arthur Conan Doyle, art@TheQueensMen.co.uk, 0>
<User: TheRealMT, Mark Twain, samul@clemens.org, 0>

實踐中,設計HBase 表模式時這種排序設計是一個關鍵考慮因素。這是另一個物理數據模型影響邏輯模型的地方。掌握這些細節能夠幫助你在設計模式時利用這個特性。

物理模型:面向列族

就像關係型數據庫同樣,HBase 中的表由行和列組成。HBase 中列按照列族分組。這種分組表如今映射的映射邏輯模型中是其中一個層次。列族也表如今物理模型中。每一個列族在硬盤上有本身的HFile 集合。這種物理上的隔離容許在列族底層HFile 層面上分別進行管理。進一步考慮到合併,每一個列族的HFile 都是獨立管理的。

HBase 的記錄按照鍵值對存儲在HFile 裏。HFile 自身是二進制文件,不是直接可讀的。存儲在硬盤上HFile 裏的Mark 用戶數據如圖2-8 所示。注意,在HFile 裏Mark 這一行使用了多條記錄。每一個列限定符和時間版本有本身的記錄。另外,文件裏沒有空記錄(null)。若是沒有數據,HBase 不會存儲任何東西。所以列族的存儲是面向列的,就像其餘列式數據庫同樣。一行中一個列族的數據不必定存放在同一個HFile 裏。Mark 的info數據可能分散在多個HFile 裏。惟一的要求是,一行中列族的數據須要物理存放在一塊兒。

"TheRealMT"  , "info" , "email" ,          1329088321289 ,     "samuel@clemens.org"
"TheRealMT"  , "info" , "name"            1329088321289 ,     "Mark Twain"
"TheRealMT"  , "info",  "password" ,   1329088818321 ,     "abc123",
"TheRealMT"  , "info" , "password",    1329088321289 ,     "Langhorne"

若是users 表有了另外一個列族,而且Mark 在那些列裏有數據。Mark 的行也會在那些HFile 裏有數據。每一個列族使用本身的HFile 意味着,當執行讀操做時HBase 不須要讀出一行中全部的數據,只須要讀取用到列族的數據。面向列意味着當檢索指定單元時,HBase 不須要讀佔位符(placeholder)記錄。這兩個物理細節有利於稀疏數據集合的高效存儲和快速讀取。

讓咱們增長另一個列族到users 表,以存儲TwitBase 網站上的活動,這會生成多個HFile。讓HBase 管理整行的一整套工具如圖所示。HBase 稱這種機制爲region,咱們在後面會討論。

20160318171023

在圖中能夠看到,訪問不一樣列族的數據涉及徹底不一樣的MemStore 和HFile。列族activity 數據的增加並不影響列族info 的性能。

相關文章
相關標籤/搜索