轉載地址:https://dxer.github.io/2016/03/18/hbase/
HBase一些基本概念
1、Row key 行主鍵,在對HBase進行查詢時候只能依靠Row key,HBase不支持條件查詢等類似於一些主流數據庫的查詢方式,讀取記錄只能依賴行主鍵以及進行全局掃面,可以將行主鍵想象成主流數據庫查詢過程中用到的主鍵(例如,id)。
2、Column Family 列族,可以將列族想象成日常主流數據庫中的表結構的所有列的一個大管家,列族中存儲了所有列的名稱,整個表包括多少列,列族就包括多少(除去Row key和Timestamp列)。
3、Column 列,HBase的每個列都隸屬於一個列族,以列族名稱作爲前綴,同一列族中的所有列會聚集在一個存儲單元上,同時按照Column key進行排序。
4、Timestamp 在HBase中,通過row key 和 Colum Family確定一份數據,同一個row key和Colum Family可能有多份不同的數據,HBase通過時間戳來區分這些數據,同時按照時間戳對左右的數據進行排序,最新的數據排在最前面,時間戳默認爲系統當前時間(精確到毫秒),同時也可以人爲設置該值。
5、Value 我們在HBase表中精確查詢數據時,通過TableName找到表,接着通過Row key找到對應的行,然後通過ColumnKey找到相應的列,最後根據時間戳找到最新的需要查詢的值,這個值就是value。
6、存儲類型 在HBase中,表名稱是字符串,行鍵和列名稱是二進制值(即就是Java中的Byte[]),時間戳是一個64爲的整數(Java中的long類型),最後的查詢結果Value是字節數組(Java中的byte[]類型)。
7、存儲結構
在HBase中,整個數據表是按照行鍵進行排序,每行包括任意數量的列,列和列之間通過列鍵進行排序,每列包括若干的數據,整個HBase的存儲結構可以理解如下:
1
|
Table(
|
HBase數據模型
- 表(table):HBase用表組織數據。表名是字符串(String),由可以在文件系統路徑裏使用的字符組成。
- 行(row):在表裏,數據按行存儲。行由行健(rowkey)唯一標識。行健沒有數據類型,視爲字節數組byte[]。
- 列族(column family):行裏的數據按照列族進行分組,列族也影響到HBase數據的物理存放。因此,他們必須事前定義並且不輕易修改。表中每行擁有相同列族,儘管行不需要在每個列族裏存儲數據,列族名字是字符串(String),由可以在文件系統路徑裏使用的字符組成。
- 列限定符(column qualifier):列族裏的數據通過列限定符或列來定位。列限定符不必事前定義。列限定符不必在不同行之間保持一致。就像行健一樣,類限定符沒有數據類型,視爲字節數據byte[]。
- 單元(cell):行健、列族和列限定符一起確定一個單元。存儲在單元裏的數據成爲單元值(value)。值沒有數據類型,視爲字節數組byte[]。
- 時間版本(version):單元值有時間版本。時間版本用時間戳標識,是一個long型。沒有指定時間版本時,當前時間戳作爲操作的基礎。HBase保留單元值時間版本的數量基於列族進行配置。默認3個版本。
數據座標
行健、列族、列限定符和時間版本
寫
執行寫入的時候會寫到兩個文件:預寫式日誌(write-ahead log,也稱HLog)和MemStore。HBase的默認方式是把寫入動作記錄在這兩個地方,以保證數據持久化。只有當這兩個地方的變化信息都寫入並確認後,才認爲寫動作完成。
MemStore是內存裏的寫入緩衝區,HBase中數據在永久寫入硬盤之前在這裏積累。當MemStore填滿後,其中的數據會刷寫到硬盤,生成一個HFile文件。HFile是HBase使用底層存儲格式。HFile對應列族,一個列族可以有多個HFile,但一個HFile不能存儲多個列族的數據。在集羣的每個節點上,每個列族都有一個MemStore。
注:不寫入WAL會在RegionServer故障時增加丟失數據的風險。關閉WAL,出現故障時HBase可能無法恢復數據,沒有刷寫到硬盤的所有寫入數據都會丟失。
讀
HBase在讀操作上使用了LRU(最近最少使用算法)緩存技術。也叫作BlockCache。BlockCache設計用來保存從HFile裏讀入內存的頻繁訪問的數據,避免硬盤讀。每個列族都有自己的BlockCache。
BlockCache中的Block是HBase從硬盤完成一次讀取的數據單位。HFile物理存放形式是一個Block的序列外加這些Block的索引。從HBase中讀取一個Block需要先將索引上查找一次改Block然後從硬盤讀出、Block是建立索引的最小數據單位,也是從硬盤讀取的最小數據單位。Block大小按照列族設定,默認是64kb。如果主要用於隨機查詢,可能需要細粒度的Block索引,小一點兒的Block更好一些。Block變小會導致索引變大,進而消耗更多內存。如果經常執行順序掃描,一次讀取多個Block,大一點的Block更好一些。Block變大意味着索引項變少,索引編寫,因此節省內存。
從HBase總讀出一行,首先會檢查MemStore等待修改的隊列,然後檢查BlockCache看包含改行的Blocj是否最近被訪問過,最後訪問硬盤上對應的HFile。
刪
執行HBase刪除命令的時候,實際上數據並不會立即刪除,只是會在該數據上打上刪除的記錄。被標記的記錄不能在Get和Scan命令中返回結果。因爲HFile文件是不能改變的,直到執行一次大合併,含有這些標記的數據纔會被處理,被刪除的數據佔用的空間纔會釋放。
大合併(major compaction):處理給定region的一個列族的所有HFile。大合併完成後,這個列族的所有HFile合併成一個文件,可以從Shell中收工出發整個表(或者特定region)的大合併。大合併是HBase清理被刪除記錄的唯一機會
小合併(minor compaction):把多個小HFile合併成一個大HFile。
HBase Shell命令
Command | 描述 |
---|---|
alter | 修改列族模式 |
count | 統計表中行的數量 |
create | 創建表 |
describe | 顯示錶相關的詳細信息 |
delete | 刪除指定對象的值(可以爲表,行,列對應的值,另外也可以指定時間戳的值) |
deleteall | 刪除指定行的所有元素值 |
disable | 使表無效 |
enable | 使表有效 |
drop | 刪除表 |
exists | 測試表是否存在 |
exit | 退出HBase Shell的值 |
get | 獲取行或單元的值 |
incr | 增加指定表、行或列的值 |
list | 列出HBase中存在的所有表 |
put | 向指定的表單元添加值 |
tools | 列出HBase所支持的工具 |
scan | 通過對錶的掃描來獲取對應的值 |
status | 返回HBase集羣的狀態信息 |
shutdown | 關閉HBase集羣(與exit不同) |
truncate | 重新創建指定表 |
version | 返回HBase版本信息 |
create
創建表
1
|
|
list
列出HBase中包含的表名稱
put
向指定表中添加值
1
|
put 't1', 'rowkey', 'cf:name', 'test', ts
|
scan
對錶的掃描來獲取對應的值
1
|
scan 't1'
|
get
獲取行或者單元的值。
1
|
get 't1', 'rowkey'
|
注:COLUMN和COLUMNS是不同的,scan操作中的COLUMNS指定的是表的列族,get操作中的COLUMN指定的是特定的列,COLUMN的值是指上是”列族+列修飾符”