Hbase關鍵的幾個點
一. 什么時候需要HBase
-
半結構化或非結構化數據
對于數據結構字段不夠確定或雜亂無章很難按一個概念去進行抽取的數據適合用HBase。當業務發展需要存儲author的email,phone,address信息時RDBMS需要停機維護,而HBase支持動態增加.
-
記錄非常稀疏
RDBMS的行有多少列是固定的,為null的列浪費了存儲空間。而如上文提到的,HBase為null的Column不會被存儲,這樣既節省了空間又提高了讀性能。
-
多版本數據
如上文 提到的根據Row key和Column key定位到的Value可以有任意數量的版本值,因此對于需要存儲變動歷史記錄的數據,用HBase就非常方便了。比如上例中的author的 Address是會變動的,業務上一般只需要最新的值,但有時可能需要查詢到歷史值。
-
超大數據量
當數據 量越來越大,RDBMS數據庫撐不住了,就出現了讀寫分離策略,通過一個Master專門負責寫操作,多個Slave負責讀操作,服務器成本倍增。隨著壓 力增加,Master撐不住了,這時就要分庫了,把關聯不大的數據分開部署,一些join查詢不能用了,需要借助中間層。隨著數據量的進一步增加,一個表 的記錄越來越大,查詢就變得很慢,于是又得搞分表,比如按ID取模分成多個表以減少單個表的記錄數。經歷過這些事的人都知道過程是多么的折騰。采用 HBase就簡單了,只需要加機器即可,HBase會自動水平切分擴展,跟Hadoop的無縫集成保障了其數據可靠性(HDFS)和海量數據分析的高性能 (MapReduce)
二. HTable一些基本概念
-
Row key
行主鍵, HBase不支持條件查詢和Order by等查詢,讀取記錄只能按Row key(及其range)或全表掃描,因此Row key需要根據業務來設計以利用其存儲排序特性(Table按Row key字典序排序如1,10,100,11,2)提高性能。
-
Column Family(列族)
在表創建時聲明,每個Column Family為一個存儲單元。在上例中設計了一個HBase表blog,該表有兩個列族:article和author。
-
Column(列)
HBase的每個列都屬于一個列族,以列族名為前綴,如列article:title和article:content屬于article列族,author:name和author:nickname屬于author列族。
Column不用創建表時定義即可以動態新增,同一Column Family的Columns會群聚在一個存儲單元上,并依Column key排序,因此設計時應將具有相同I/O特性的Column設計在一個Column Family上以提高性能。
-
Timestamp
HBase 通過row和column確定一份數據,這份數據的值可能有多個版本,不同版本的值按照時間倒序排序,即最新的數據排在最前面,查詢時默認返回最新版本。 如上例中row key=1的author:nickname值有兩個版本,分別為1317180070811對應的“一葉渡江”和1317180718830對應的 “yedu”(對應到實際業務可以理解為在某時刻修改了nickname為yedu,但舊值仍然存在)。Timestamp默認為系統當前時間(精確到毫 秒),也可以在寫入數據時指定該值。
-
Value
每個值 通過4個鍵唯一索引,tableName+RowKey+ColumnKey+Timestamp=>value,例如上例中 {tableName=’blog’,RowKey=’1’,ColumnName=’author:nickname’,Timestamp=’ 1317180718830’}索引到的唯一值是“yedu”。
- 存儲類型
- TableName 是字符串
- RowKey 和 ColumnName 是二進制值(Java 類型 byte[])
- Timestamp 是一個 64 位整數(Java 類型 long)
- value 是一個字節數組(Java類型 byte[])。
將HTable的存儲結構理解為
即HTable按Row key自動排序,每個Row包含任意數量個Columns,Columns之間按Column key自動排序,每個Column包含任意數量個Values。理解該存儲結構將有助于查詢結果的迭代。
三. 模式設計應遵循的原則
-
列族的數量以及列族的勢
列族的數量越少越好,牽扯到了hbase的flushing;同一個表中不同列族所存儲的記錄數量的差別也需要考慮(列族的勢),會造成記錄數量少的列族的數據分散在多個region上,影響查詢效率。
-
行鍵的設計
避免使用時序或者單調(遞增/遞減)行鍵,否則會導致連續到來的數據會被分配到統一region中。
-
盡量最小化行鍵和列族的大小
避免hbase的索引過大,加重系統存儲的負擔
-
版本的數量
HColumnDescriptor設置版本的數量,避免設置過大,版本保留過多。