HBase Shell及其常用指令
HBase 資料庫預設的用戶端程式是 HBase Shell,它是一個指令行工具。使用者可以使用 HBase Shell,通過指令行的方式與 HBase 進行互動。
HBase Shell 是一個封裝了 Java 用戶端 API 的 JRuby 應用軟體,在 HBase 的 HMaster 主機上通過指令行輸入 hbase shell,即可進入 HBase 指令行環境,如圖 1 所示。

圖 1:HBase Shell 指令行環境
在 Shell 中輸入help可以擷取可用指令清單,輸入help commandname可擷取特定指令的幫助,還可以輸入各種指令檢視叢集、資料庫和資料的各項詳情。
例如,使用status指令檢視目前叢集各節點的狀态,使用version指令檢視目前 HBase 的版本号,輸入指令exit或quit即可退出 HBase Shell。
下面對常用指令做一下彙總。
HBase Shell 資料表指令 | |
指令 | 描述 |
create | 建立指定模式的新表 |
alter | 修改表的結構,如添加新的列族 |
describe | 展示表結構的資訊,包括列族的數量與屬性 |
list | 列出 HBase 中已有的表 |
disable/enable | 為了删除或更改表而禁用一個表,更改完後需要解禁表 |
disable_all | 禁用所有的表,可以用正規表達式比對表 |
is_disable | 判斷一個表是否被禁用 |
drop | 删除表 |
truncate | 如果隻是想删除資料而不是表結構,則可用 truncate 來禁用表、删除表并自動重建表結構 |
HBase Shell 增删改查指令 | |
put | 添加一個值到指定單元格中 |
get | 通過表名、行鍵等參數擷取行或單元格資料 |
scan | 周遊表并輸出滿足指定條件的行記錄 |
count | 計算表中的邏輯行數 |
delete | 删除表中列族或列的資料 |
HBase建立表(create指令)
與關系型資料庫不同,在 HBase 中,基本組成為表,不存在多個資料庫。是以,在 HBase 中存儲資料先要建立表,建立表的同時需要設定列族的數量和屬性。
示例:Student 資料表 | |||||||
行鍵 | 列族 StuInfo | 列族 Grades | 時間戳 | ||||
Name | Age | Sex | Class | BigData | Computer | Math | |
0001 | Tom Green | 18 | Male | 80 | 90 | 85 | T2 |
0002 | Amy | 19 | 95 | 89 | T1 | ||
0003 | Allen | 88 |
HBase 使用 creat 指令來建立表,建立表時需要指明表名和列族名,如建立上表中的學生資訊表 Student 的指令如下:
create 'Student','StuInfo','Grades'
這條指令倉建了名為 Student 的表,表中包含兩個列族,分别為 Stulnfo 和 Grades。
注意在 HBase Shell 文法中,所有字元串參數都必須包含在單引号中,且區分大小寫,如 Student 和 student 代表兩個不同的表。
另外,在上條指令中沒有對列族參數進行定義,是以使用的都是預設參數,如果建表時要設定列族的參數,參考以下方式:
create 'Student', {NAME => 'Stulnfo', VERSIONS => 3}, {NAME =>'Grades', BLOCKCACHE => true}
大括号内是對列族的定義,NAME、VERSION 和 BLOCKCACHE 是參數名,無須使用單引号,符号=>表示将後面的值賦給指定參數。例如,VERSIONS => 3是指此單元格内的資料可以保留最近的 3 個版本,BLOCKCACHE => true指允許讀取資料時進行緩存。
建立表結構以後,可以使用 exsits 指令檢視此表是否存在,或使用 list 指令檢視資料庫中所有表,如下圖所示。
圖 2:exsits 和 list 指令
還可以使用 describe 指令檢視指定表的列族資訊,如下圖所示。
圖 3:describe 指令
describe 指令描述了表的詳細結構,包括有多少個列族、每個列族的參數資訊,這些顯示的參數都可以使用 alter 指令進行修改。
Student表完整語句 create 'Student',{NAME=>'StuInfo',VERSIONS=>'3'},'Grades' put 'Student', '0001', 'StuInfo:Name', 'Tom Green', 1 put 'Student', '0001', 'StuInfo:Age', '18' put 'Student', '0001', 'StuInfo:Sex', 'Male' put 'Student', '0001', 'Grades:BigData', '80' put 'Student', '0001', 'Grades:Computer', '90' put 'Student', '0001', 'Grades:Math', '85' put 'Student', '0002', 'StuInfo:Name', 'Amy' put 'Student', '0002', 'StuInfo:Age', '19' put 'Student', '0002', 'Grades:BigData', '95' put 'Student', '0002', 'Grades:Math', '89' put 'Student', '0003', 'StuInfo:Name', 'Allen' put 'Student', '0003', 'StuInfo:Age', '19' put 'Student', '0003', 'StuInfo:Sex', 'Male' put 'Student', '0003', 'StuInfo:Class', '02' put 'Student', '0003', 'Grades:BigData', '90' put 'Student', '0003', 'Grades:Math', '88' |
HBase修改表(alter指令)
HBase 表的結構和表的管理可以通過 alter 指令來完成,使用這個指令可以完成更改列族參數資訊、增加列族、删除列族以及更改表的相關設定等操作。
修改列族
首先修改列族的參數資訊,如修改列族的版本。例如上面的 Student 表,假設它的列族 Grades 的 VERSIONS 為 1,但是實際可能需要儲存最近的 3 個版本,可使用以下指令完成:
alter 'Student', {NAME => 'Grades', VERSIONS => 3}
修改多個列族的參數,形式與 create 指令類似。
這裡要注意,修改已存有資料的列族屬性時,HBase 需要對列族裡所有的資料進行修改,如果資料量很大,則修改可能要占很長時間。
增加列族
如果需要在 Student 表中新增一個列族 hobby,使用以下指令:
alter 'Student', 'hobby'
删除列族
如果要移除或者删除已有的列族,以下兩條指令均可完成:
alter 'Student', { NAME => 'hobby', METHOD => 'delete' }
alter 'Student', 'delete' => 'hobby'
另外,HBase 表至少要包含一個列族,是以當表中隻有一個列族時,無法将其删除。
HBase删除表(disable和drop指令)
HBase 使用 drop 指令删除表,但是在删除表之前需要先使用 disable 指令禁用表。
例如有一個 Student 表,删除該表的完整流程如下:
disable 'Student'
drop 'Student'
使用 disable 禁用表以後,可以使用 is_disable 檢視表是否禁用成功。
另外,如果隻是想清空表中的所有資料,使用 truncate 指令即可,此指令相當于完成禁用表、删除表,并按原結構重建立立表操作:
truncate 'Student'
HBase put指令:插入資料
HBase 使用 put 指令向資料表中插入資料,put 向表中增加一個新行資料,或覆寫指定行的資料。
例如有以上結構的資料表,向其中插入一條資料的寫法為:
put 'Student', '0001', 'Stulnfo:Name', 'Tom Green', 1
在上述指令中:
- 第一個參數Student為表名;
- 第二個參數0001為行鍵的名稱,為字元串類型;
- 第三個參數StuInfo:Name為列族和列的名稱,中間用冒号隔開。列族名必須是已經建立的,否則 HBase 會報錯;列名是臨時定義的,是以列族裡的列是可以随意擴充的;
- 第四個參數Tom Green為單元格的值。在 HBase 裡,所有資料都是字元串的形式;
- 最後一個參數1為時間戳,如果不設定時間戳,則系統會自動插入目前時間為時間戳。
注意,put 指令隻能插入一個單元格的資料,上表中的一行資料需要通過以下幾條指令一起完成:
如果 put 語句中的單元格是已經存在的,即行鍵、列族及列名都已經存在,且不考慮時間戳的情況下,執行 put 語句,則可對資料進行更新操作。
如以下指令可将行鍵為 0001 的學生姓名改為 Jim Green:
put 'Student', '0001', 'Stulnfo:Name', 'Jim Green'
如果在初始建立表時,已經設定了列族 VERSIONS 參數值為 n,則 put 操作可以儲存 n 個版本資料,即可查詢到行鍵為 0001 的學生的 n 個版本的姓名資料。
HBase删除資料(delete指令)
HBase delete 指令可以從表中删除一個單元格或一個行集,文法與 put 類似,必須指明表名和列族名稱,而列名和時間戳是可選的。
例如,執行以下指令,将删除 Student 表中行鍵為 0002 的 Grades 列族的所有資料:
delete 'Student', '0002', 'Grades'
需要注意的是,delete 操作并不會馬上删除資料,隻會将對應的資料打上删除标記(tombstone),隻有在合并資料時,資料才會被删除。
另外,delete 指令的最小粒度是單元格(Cell)。例如,執行以下指令将删除 Student 表中行鍵為 0001,Grades 列族成員為 Math,時間戳小于等于 2 的資料:
delete 'Student', '0001', 'Grades:Math', 2
delete 指令不能跨列族操作,如需删除表中所有列族在某一行上的資料,即删除上表中一個邏輯行,則需要使用 deleteall 指令,如下所示,不需要指定列族和列的名稱:
deleteall 'Student', '0001'
HBase get指令:從表中擷取資料
HBase get 指令可以從資料表中擷取某一行記錄,類似于關系型資料庫中的 select 操作。get 指令必須設定表名和行鍵名,同時可以選擇指明列族名稱、時間戳範圍、資料版本等參數。
例如,對于上面的資料表,執行以下指令可以擷取 Student 表中行鍵為 0001 的所有列族資料:
get 'Student', '0001'
下圖展示了在 get 語句中使用限定詞 VERSIONS 後擷取的資料内容。
上圖中首先 put 三條資料,因為初始建立 Student 表和 Stulnfo 列族時,已經設定 VERSIONS 為 3,即使用 get 擷取資料時最多得到 3 個版本的資料。
上圖中的 get 指令使用了限定詞 VERSIONS=>2,是以 get 得到的資料隻顯示了 Stulnfo:Name 最小的兩個版本。
HBase scan指令:查詢全表資料
HBase scan 指令用來查詢全表資料,使用時隻需指定表名即可。
例如對于上面的 Student 表,使用下面的寫法即可查詢資料:
scan 'Student'
同樣地,還可以指定列族和列的名稱,或指定輸出行數,甚至指定輸出行鍵範圍,如下圖所示。
scan 指定條件輸出時,需要使用大括号将參數包含起來。
注意指定列族和列名稱使用 COLUMN 限定符;指定輸出行鍵範圍使用 STARTROW 和 ENDROW 限定符,此時輸出行不包括 ENDROW 行。例如,上圖中 ENDROW=>0003,隻會輸出行鍵為 0002 的記錄,不會輸出 0003 記錄。
HBase還支援LIMIT(限制查詢結果行數),STARTROW(ROWKEY起始行。會先根據這個key定位到region,再向後掃描)、STOPROW/ENDROW(結束行)、TIMERANGE(限定時間戳範圍)、VERSIONS(版本數)、和FILTER(按條件過濾行)等。上述限定條件也可以聯合使用,中間用逗号隔開即可。
在 HBase 中,具有相同行鍵的單元格,無論其屬于哪個列族,都可以将整體看作一個邏輯行, 使用 count 指令可以計算表的邏輯行數。
在關系型資料庫中,有多少條記錄就有多少行,表中的行數很容易統計。而在 HBase 裡,計算邏輯行需要掃描全表的内容,重複的行鍵是不納入計數的,且标記為 tombstone 的删除資料也不納入計數。
執行 count 指令其實是一個開銷較大的程序,特别是應用在大資料場景時,可能需要持續很長時間,是以,使用者一般會結合 Hadoop 的 MapReduce 架構來進行分布式的掃描計數。
HBase過濾器入門Filter
在 HBase 中,get 和 scan 操作都可以使用過濾器來設定輸出的範圍,類似 SQL 裡的 Where 查詢條件。
使用 show_filter 指令可以檢視目前 HBase 支援的過濾器類型,如下圖所示。
使用上述過濾器時,一般需要配合比較運算符或比較器使用,如下面兩個表所示。
比較運算符 | |
= | 等于 |
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
!= | 不等于 |
比較器 | |
BinaryComparator | 比對完整位元組數組 |
BinaryPrefixComparator | 比對位元組數組字首 |
BitComparator | 比對比特位 |
NullComparator | 比對空值 |
RegexStringComparator | 比對正規表達式 |
SubstringComparator | 比對子字元串 |
使用過濾器的文法格式如下所示:
scan '表名', { Filter => "過濾器(比較運算符, '比較器') }
在上述文法中,Filter=> 指明過濾的方法,整體可用大括号引用,也可以不用大括号。過濾的方法用雙引号引用,而比較方式用小括号引用。
下面介紹常見的過濾器使用方法。
行鍵過濾器
RowFilter 可以配合比較器和運算符,實作行鍵字元串的比較和過濾。例如,比對行鍵中大于 0001 的資料,可使用 binary 比較器;比對以 0001 開頭的行鍵,可使用 substring 比較器,注意 substring 不支援大于或小于運算符。
實作上述比對條件的過濾指令以及顯示結果如下圖所示。
針對行鍵進行比對的過濾器還有 PrefixFilter、KeyOnlyFilter、FirstKeyOnlyFilter 和 InclusiveStopFilter,其具體含義和使用示例如下表所示。
其中,FirstKeyOnlyFilter 過濾器可以用來實作對邏輯行進行計數的功能,并且比其他計數方式效率高。
其他行鍵過濾器描述 | ||
示例 | ||
PrefixFilter | 行鍵字首比較器,比較行鍵字首 | scan 'Student', FILTER => "PrefixFilter('0001')" 同 scan 'Student', FILTER => "RowFilter(=,'substring:0001')" |
KeyOnlyFilter | 隻對單元格的鍵進行過濾和顯示,不顯示值 | scan 'Student', FILTER => "KeyOnlyFilter()" |
FirstKeyOnlyFilter | 隻掃描顯示相同鍵的第一個單元格,其鍵值對會顯示出來 | scan 'Student', FILTER => "FirstKeyOnlyFilter()" |
InclusiveStopFilter | 替代 ENDROW 傳回終止條件行 | scan 'Student', { STARTROW => '0001', FIILTER => "InclusiveStopFilter('binary:0002')" } scan 'Student', { STARTROW => '0001', ENDROW => '0003' } |
上表中的指令示例操作結果如下圖所示。
列族與列過濾器
針對列族進行過濾的過濾器為 FamilyFilter,其文法結構與 RowFilter 類似,不同之處在于 FamilyFilter 是對列族名稱進行過濾的。
例如,以下指令掃描Student表顯示列族為 Grades 的行。
scan 'Student', FILTER=>" FamilyFilter(= , 'substring:Grades')"
針對列的過濾器如下表所示,這些過濾器也需要結合比較運算符和比較器進行列族或列的掃描過濾。
列過濾器描述 | ||
列過濾器 | ||
QualifierFilter | 列辨別過濾器,隻顯示對應列名的資料 | scan 'Student', FILTER => "QualifierFilter(=,'substring:Math')" |
ColumnPrefixFilter | 對列名稱的字首進行過濾 | scan 'Student', FILTER => "ColumnPrefixFilter('Ma')" |
MultipleColumnPrefixFilter | 可以指定多個字首對列名稱過濾 | scan 'Student', FILTER => "MultipleColumnPrefixFilter('Ma','Ag')" |
ColumnRangeFilter | 過濾列名稱的範圍 | scan 'Student', FILTER => "ColumnRangeFilter('Big',true,'Math',false')" |
上表中 QualifierFilter 和 ColumnPrefixFilter 過濾效果類似,隻是 ColumnPrefixFilter 無須結合運算符和比較器即可完成字元串字首的過濾。
MultipleColumnPrefixFilter 過濾器是對 ColumnPrefixFilter 的延伸,可以一次過濾多個列字首。
ColumnRangeFilter過濾器則可以掃描出符合過濾條件的列範圍,起始和終止列名用單引号引用,true 和 false 參數可指明結果中包含的起始或終止列。
上表中的過濾器示例在 HBase Shell 中掃描結果如下圖所示。
值過濾器
在 HBase 的過濾器中也有針對單元格進行掃描的過濾器,即值過濾器,如下表所示。
值過濾器描述 | ||
ValueFilter | 值過濾器,找到符合值條件的鍵值對 | scan 'Student', FILTER => "ValueFilter(=,'substring:curry')" get 'Student', '0001', FILTER => "ValueFilter(=,'substring:curry')" |
SingleColumnValueFilter | 在指定的列族和列中進行比較的值過濾器 | scan 'Student', Filter => "SingleColumnValueFilter('StuInfo', 'Name', =, 'binary:curry')" |
SingleColumnValueExcludeFilter | 排除比對成功的值 | scan 'Student', Filter => "SingleColumnValueExcludeFilter('StuInfo', 'Name', =, 'binary:curry')" |
ValueFilter 過濾器可以利用 get 和 scan 方法對單元格進行過濾,但是使用 get 方法時,需要指定行鍵。
SingleColumnValueFilter 和 SingleColumnValueExcludeFilter 過濾器掃描的結果是相反的, 都需要在過濾條件中指定列族和列的名稱。
上表中的值過濾器示例在 HBase Shell 中掃描結果如下圖所示。
其他過濾器
還有一些其他的過濾器,其過濾方式和示例如下表所示。
其他過濾器描述 | ||
ColumnCountGetFilter | 限制每個邏輯行傳回鍵值對的個數,在 get 方法中使用 | get 'Student', '0001', FILTER => "ColumnCountGetFilter(3)" |
TimestampsFilter | 時間戳過濾,支援等值,可以設定多個時間戳 | scan 'Student', Filter => "TimestampsFilter(1,4)" |
設定停止行 | scan 'Student', { STARTROW => '0001', ENDROW => '0005', FILTER => "InclusiveStopFilter('0003')" } | |
PageFilter | 對顯示結果按行進行分頁顯示 | scan 'Student', { STARTROW => '0001', ENDROW => '0005', FILTER => "PageFilter(3)" } |
ColumnPaginationFilter | 對一行的所有列分頁,隻傳回 [offset,offset+limit] 範圍内的列 | scan 'Student', { STARTROW => '0001', ENDROW => '0005', FILTER => "ColumnPaginationFilter(2,1)" } |
ColumnCountGetFilter 過濾器限制每個邏輯行傳回多少列,一般不用在 scan 方法中,Timestamps Filter 比對相同時間戳的資料。
InclusiveStopFilter過濾器設定停止行,且包含停止的行,上表中示例最終展示資料為行鍵 0001〜0003 範圍内的資料。PageFilter 設定每頁最多顯示多少邏輯行, 示例中顯示三個邏輯行。
ColumnPaginationFilter過濾器對一個邏輯行的所有列進行分頁顯示。
小問題:
在hbase shell中如果指令輸入錯誤,很難退出。查了網上一個非百分百有效的方法是輸入 >' 然後回車。測試部分情況下有效果,但有時也無效,隻能ctrl+c退出用戶端。如果有哪位同學有好辦法請在評論區留言。