HBase 系列 - HBase 基本概念#
內容整理自:
- Github 倉庫: God-Of-BigData/HBase 系列
基本概念#
數據在 HBase 中邏輯意義上的排布:
Row-Key | Value(CF、Qualifier、Version) |
---|---|
1 | info {' 姓 ': ' 張 ',' 名 ':' 三 '} pwd {' 密碼 ': '111'} |
2 | Info {' 姓 ': ' 李 ',' 名 ':' 四 '} pwd {' 密碼 ': '222'} |
數據在 HBase 中物理上的排布:
Row-Key | CF | 時間戳 | Cell Value |
---|---|---|---|
1 | info | 123456789 | 張 |
1 | info | 123456789 | 三 |
2 | info | 123456789 | 李 |
2 | info | 123456789 | 四 |
Row key (行鍵)#
-
Row Key
是用來檢索記錄的主鍵,訪問 HBase 中的數據只能通過 Rowkey、Rowkey 的 range 或者全表掃描三種方式,全表掃描性能太差 -
Row Key
可以是任意字符串,存儲時按照字典序進行排序,需要注意:- 因為字典序對 Int 排序的結果是 1,10,100,11,18,19,2,20,21,…,9,91,...,99。如果你使用整型的字符串作為行鍵,那麼為了保持整型的自然序,行鍵必須用 0 作左填充
- 行的一次讀寫操作是原子性的 (不論一次讀寫多少列)
Column Family (列族)#
HBase 表中的每個列,都歸属于某個列族。列族是表的 Schema 的一部分,所以列族需要在創建表時進行定義。列族的所有列都以列族名作為前綴,例如 info:ln
,info:fn
都屬於 info
這個列族
Column Qualifier (列限定符)#
可以理解為是具體的列名,例如 info:ln
,info:fn
都屬於 info
這個列族,它們的列限定符分別是 ln
和 fn
。需要注意的是列限定符不是表 Schema 的一部分,你可以在插入數據的過程中動態創建列
Column (列)#
HBase 中的列由列族和列限定符組成,它們由 :
(冒號) 進行分隔,即一個完整的列名應該表述為 列族名 :列限定符
Cell#
HBase 中通過 row key
和 column
確定的為一個存儲單元稱為 Cell
, 是行,列族和列限定符的組合,並包含值和時間戳
TimeStamp (時間戳)#
每個 Cell
都保存著同一份數據的多個版本。版本通過時間戳來索引
,時間戳的類型是 64 位整型,時間戳可以由 HBase 在數據寫入時自動賦值,也可以由客戶顯式指定。每個 Cell
中,不同版本的數據按照時間戳倒序排列,即最新的數據排在最前面
Rowkey 設計原則#
打散 Rowkey
HBase 中的行是按照 RowKey 字典序排序的。這對 Scan 操作非常友好,因為 RowKey 相近的行總是存儲在相近的位置,順序讀的效率比隨機讀要高。但是,如果大量的讀寫操作總是集中在某個 RowKey 範圍,那麼就會造成 Region 熱點,拖累 RegionServer 的性能。因此,要適當地將 RowKey 打散
控制 RowKey 長度
- 在 HBase 的底層存儲 HFile 中,RowKey 是 KeyValue 結構中的一個域。假設 RowKey 長度 100B,那麼 1000 萬條數據中,只算 RowKey 就占用掉將近 1G 空間,會影響 HFile 的存儲效率
- HBase 中設計有 MemStore 和 BlockCache,分別對應列族 / Store 級別的寫入緩存,和 RegionServer 級別的讀取緩存。如果 RowKey 過長,緩存中存儲數據的密度就會降低,影響數據落地或查詢效率
保證 RowKey 唯一性
存儲結構#
Regions#
-
HBase Table 中的所有行按照
Row Key
的字典序排列。HBase Tables 通過行鍵的範圍 (row key range) 被水平切分成多個Region
, 一個Region
包含了在 start key 和 end key 之間的所有行 -
每個表一開始只有一個
Region
,隨著數據不斷增加,Region
會不斷增大,當增大到一個閾值的時候,Region
就會等分為兩個新的Region
。當 Table 中的行不斷增多,就會有越來越多的Region
-
Region
是 HBase 中分佈式存儲和負載均衡的最小單元。這意味著不同的Region
可以分佈在不同的Region Server
上。但一個Region
是不會拆分到多個 Server 上的
Region Server#
Region Server
運行在 HDFS 的 DataNode 上。它具有以下組件:
- WAL (Write Ahead Log,預寫日誌):用於存儲尚未進持久化存儲的數據記錄,以便在發生故障時進行恢復。
- BlockCache:讀緩存。它將頻繁讀取的數據存儲在內存中,如果存儲不足,它將按照
最近最少使用原則
清除多餘的數據。 - MemStore:寫緩存。它存儲尚未寫入磁碟的新數據,並會在數據寫入磁碟之前對其進行排序。每個 Region 上的每個列族都有一個 MemStore。
- StoreFile :StoreFile 底層是
HFile
,HFile 是 Hadoop 的二進制格式文件,將行數據按照 Key\Values 的形式存儲在文件系統上
Region Server 存取一個子表時,會創建一個 Region 對象,然後對表的每個列族創建一個 Store
實例,每個 Store
會有 0 個或多個 StoreFile
與之對應,每個 StoreFile
則對應一個 HFile
,HFile 就是實際存儲在 HDFS 上的文件
系統架構#
HBase 系統遵循 Master/Salve 架構,由三種不同類型的組件組成:
Zookeeper
- 保證任何時候,集群中只有一個 Master;
- 存儲所有 Region 的尋址入口;
- 實時監控 Region Server 的狀態,將 Region Server 的上線和下線信息實時通知給 Master;
- 存儲 HBase 的 Schema,包括有哪些 Table,每個 Table 有哪些 Column Family 等信息。
Master
- 為 Region Server 分配 Region ;
- 負責 Region Server 的負載均衡 ;
- 發現失效的 Region Server 並重新分配其上的 Region;
- GFS 上的垃圾文件回收;
- 處理 Schema 的更新請求。
Region Server
- Region Server 負責維護 Master 分配給它的 Region ,並處理發送到 Region 上的 IO 請求;
- Region Server 負責切分在運行過程中變得過大的 Region。
組件間的協作#
HBase 使用 ZooKeeper 作為分佈式協調服務來維護集群中的伺服器狀態。 Zookeeper 負責維護可用服務列表,並提供服務故障通知等服務:
- 每個 Region Server 都會在 ZooKeeper 上創建一個臨時節點,Master 通過 Zookeeper 的 Watcher 機制對節點進行監控,從而可以發現新加入的 Region Server 或故障退出的 Region Server;
- 所有 Masters 會競爭性地在 Zookeeper 上創建同一個臨時節點,由於 Zookeeper 只能有一個同名節點,所以必然只有一個 Master 能夠創建成功,此時該 Master 就是主 Master,主 Master 會定期向 Zookeeper 發送心跳。備用 Masters 則通過 Watcher 機制對主 HMaster 所在節點進行監聽;
- 如果主 Master 未能定時發送心跳,則其持有的 Zookeeper 會話會過期,相應的臨時節點也會被刪除,這會觸發定義在該節點上的 Watcher 事件,使得備用的 Master Servers 得到通知。所有備用的 Master Servers 在接到通知後,會再次去競爭性地創建臨時節點,完成主 Master 的選舉