# Apache HBase Shell
> 貢獻者:[xixici](https://github.com/xixici)
Apache HBase Shell 是 [(J)Ruby](http://jruby.org)'s IRB 的基礎上增加了一些 HBase 特定的命令。你可以在 IRB 中做的任何事情,都可以在 HBase Shell 中完成。
要運行 HBase shell,請執行如下操作:
```
$ ./bin/hbase shell
```
輸入:`help`,然后按 `<RETURN>` 查看 shell 命令和選項的列表。至少瀏覽器幫助輸出末尾的段落,了解如何將變量和命令參數輸入到 HBase shell 中;尤其要注意表名、行和列等是如何引用的。
請參閱 [shell exercises](#shell_exercises)。
這是 Rajeshbabu Chintaguntla 的[所有 shell 命令](http://learnhbase.wordpress.com/2013/03/02/hbase-shell-commands/)。
## 14\. 用 Ruby 編寫腳本
有關 Apache HBase 腳本示例, 請查看 HBase _bin_ 文件夾. 查看以 _*.rb_ 結尾的文件. 執行下面操作,運行:
```
$ ./bin/hbase org.jruby.Main PATH_TO_SCRIPT
```
## 15\. 非交互方式運行 Shell
HBase Shell 先增了一種非交互方式([HBASE-11658)](https://issues.apache.org/jira/browse/HBASE-11658).非交互模式捕獲 HBase Shell 命令的退出狀態(成功或失敗),并將該狀態返回給命令解釋器。如果您使用正常的交互模式,HBase Shell 將只會返回自己的退出狀態,這幾乎總是會`0`成功的。
要調用非交互模式,請將 `-n` 或 `--non-interactive` 選項傳遞給 HBase Shell。
## 16\. 系統腳本中的 HBase Shell
您可以在操作系統腳本解釋器中使用 HBase shell,例如 Bash shell,它是大多數 Linux 和 UNIX 發行版的默認命令解釋程序。以下準則使用 Bash 語法,但可以調整為使用 C 樣式的 shell(例如 csh 或 tcsh),并且可能會修改為使用 Microsoft Windows 腳本解釋器一起使用。
> 這種方式生成 HBase Shell 命令的速度很慢,所以在決定何時將 HBase 操作與操作系統命令行相結合時,請記住這一點。
Example 4\. 傳遞命令到 HBase Shell
您可以使用 `echo` 命令和 `|`(管道)操作,以非交互模式將命令傳遞到 HBase Shell。 (詳見: [hbase.shell.noninteractive](#hbase.shell.noninteractive)) .一定要轉義 HBase 命令中的字符,否則 shell 將會解釋這些字符。一些調試級別的輸出已從下面的示例中截斷。
```
$ echo "describe 'test1'" | ./hbase shell -n
Version 0.98.3-hadoop2, rd5e65a9144e315bb0a964e7730871af32f5018d5, Sat May 31 19:56:09 PDT 2014
describe 'test1'
DESCRIPTION ENABLED
'test1', {NAME => 'cf', DATA_BLOCK_ENCODING => 'NON true
E', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0',
VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIO
NS => '0', TTL => 'FOREVER', KEEP_DELETED_CELLS =>
'false', BLOCKSIZE => '65536', IN_MEMORY => 'false'
, BLOCKCACHE => 'true'}
1 row(s) in 3.2410 seconds
```
若要取消所有輸出,請將其回顯到 /dev/null:
```
$ echo "describe 'test'" | ./hbase shell -n > /dev/null 2>&1
```
Example 5\. 檢查腳本命令的結果
由于腳本不是設計為交互式運行的,因此您需要一種方法來檢查命令是失敗還是成功。HBase shell 使用為成功的命令返回值`0`的標準約定,并為失敗的命令返回一些非零值。Bash 將命令的返回值存儲在一個名為 `$?` 的特殊環境變量中。因為每次 shell 運行任何命令時都會覆蓋該變量,所以應該將結果存儲在另一個腳本定義的變量中。
下面的這個腳本展示了一種方法來存儲返回值并根據它做出決定:
```
#!/bin/bash
echo "describe 'test'" | ./hbase shell -n > /dev/null 2>&1
status=$?
echo "The status was " $status
if ($status == 0); then
echo "The command succeeded"
else
echo "The command may have failed."
fi
return $status
```
### 16.1\. 在腳本中檢查成功或失敗
獲取退出代碼`0`意味著您腳本編寫的命令確實成功了。但是,獲取非零退出代碼并不一定意味著命令失敗。該命令可能已成功,但客戶端失去連接,或者其他事件阻礙了其成功。這是因為 RPC 命令是無狀態的。確保操作狀態的唯一方法是檢查。例如,如果你的腳本創建一個表,但返回一個非零的退出值,你應該檢查表是否實際創建,然后再試圖創建它。
## 17\. 從命令文件讀取 HBase Shell 命令
您可以將 HBase Shell 命令輸入到文本文件中,每行一個命令,并將該文件傳遞給 HBase Shell。
命令文件示例
```
create 'test', 'cf'
list 'test'
put 'test', 'row1', 'cf:a', 'value1'
put 'test', 'row2', 'cf:b', 'value2'
put 'test', 'row3', 'cf:c', 'value3'
put 'test', 'row4', 'cf:d', 'value4'
scan 'test'
get 'test', 'row1'
disable 'test'
enable 'test'
```
Example 6\. 指示 HBase Shell 執行命令
將命令文件的路徑作為 `hbase shell` 命令的唯一參數傳遞。每個命令都會執行并顯示其輸出。如果您未在腳本中包含該 `exit` 命令,則會返回到 HBase shell 提示符。沒有辦法以編程方式檢查每個單獨的命令是否成功或失敗。此外,盡管您看到每個命令的輸出,但命令本身并未回顯到屏幕,因此可能難以將命令與其輸出對齊。
```
$ ./hbase shell ./sample_commands.txt
0 row(s) in 3.4170 seconds
TABLE
test
1 row(s) in 0.0590 seconds
0 row(s) in 0.1540 seconds
0 row(s) in 0.0080 seconds
0 row(s) in 0.0060 seconds
0 row(s) in 0.0060 seconds
ROW COLUMN+CELL
row1 column=cf:a, timestamp=1407130286968, value=value1
row2 column=cf:b, timestamp=1407130286997, value=value2
row3 column=cf:c, timestamp=1407130287007, value=value3
row4 column=cf:d, timestamp=1407130287015, value=value4
4 row(s) in 0.0420 seconds
COLUMN CELL
cf:a timestamp=1407130286968, value=value1
1 row(s) in 0.0110 seconds
0 row(s) in 1.5630 seconds
0 row(s) in 0.4360 seconds
```
## 18\. 將 VM 選項傳遞給 Shell
您可以使用 `HBASE_SHELL_OPTS` 環境變量將 VM 選項傳遞到 HBase Shell 。您可以在您的環境中進行設置,例如通過編輯 _?/.bashrc_,或將其設置為啟動 HBase Shell 的命令的一部分。以下的示例設置了幾個與垃圾回收相關的變量,僅用于運行 HBase Shell 的 VM 的生命周期。為了可讀性,該命令應該在單行中全部運行,但是會被 `\` 字符打斷。
```
$ HBASE_SHELL_OPTS="-verbose:gc -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps \
-XX:+PrintGCDetails -Xloggc:$HBASE_HOME/logs/gc-hbase.log" ./bin/hbase shell
```
## 19\. 覆蓋啟動 HBase Shell 的配置
hbase-2.0.5/hbase-2.1.3/hbase-2.2.0/hbase-1.4.10/hbase-1.5.0, 您可以傳遞或覆蓋`hbase-*.xml`中指定的 hbase 配置。在命令行上傳遞前綴為`-D`的鍵/值,如下所示:
```
$ ./bin/hbase shell -Dhbase.zookeeper.quorum=ZK0.remote.cluster.example.org,ZK1.remote.cluster.example.org,ZK2.remote.cluster.example.org -Draining=false
...
hbase(main):001:0> @shell.hbase.configuration.get("hbase.zookeeper.quorum")
=> "ZK0.remote.cluster.example.org,ZK1.remote.cluster.example.org,ZK2.remote.cluster.example.org"
hbase(main):002:0> @shell.hbase.configuration.get("raining")
=> "false"
```
## 20\. Shell 技巧
### 20.1\. Table 變量
HBase 0.95 版本增加了為表提供 jruby 風格的面向對象引用的 shell 命令。以前,作用于表的所有 shell 命令都具有程序風格,該風格始終將表的名稱作為參數。HBase 0.95 引入了將表分配給 jruby 變量的功能。表引用可以用來執行數據讀寫操作,比如放入、掃描、以及管理功能(如禁用,刪除,描述表等)。
例如,以前你總是會指定一個表名:
```
hbase(main):000:0> create 't', 'f'
0 row(s) in 1.0970 seconds
hbase(main):001:0> put 't', 'rold', 'f', 'v'
0 row(s) in 0.0080 seconds
hbase(main):002:0> scan 't'
ROW COLUMN+CELL
rold column=f:, timestamp=1378473207660, value=v
1 row(s) in 0.0130 seconds
hbase(main):003:0> describe 't'
DESCRIPTION ENABLED
't', {NAME => 'f', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_ true
SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => '2
147483647', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false
', BLOCKCACHE => 'true'}
1 row(s) in 1.4430 seconds
hbase(main):004:0> disable 't'
0 row(s) in 14.8700 seconds
hbase(main):005:0> drop 't'
0 row(s) in 23.1670 seconds
hbase(main):006:0>
```
現在,您可以將該表分配給一個變量,并在 jruby shell 代碼中使用結果。
```
hbase(main):007 > t = create 't', 'f'
0 row(s) in 1.0970 seconds
=> Hbase::Table - t
hbase(main):008 > t.put 'r', 'f', 'v'
0 row(s) in 0.0640 seconds
hbase(main):009 > t.scan
ROW COLUMN+CELL
r column=f:, timestamp=1331865816290, value=v
1 row(s) in 0.0110 seconds
hbase(main):010:0> t.describe
DESCRIPTION ENABLED
't', {NAME => 'f', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_ true
SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => '2
147483647', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false
', BLOCKCACHE => 'true'}
1 row(s) in 0.0210 seconds
hbase(main):038:0> t.disable
0 row(s) in 6.2350 seconds
hbase(main):039:0> t.drop
0 row(s) in 0.2340 seconds
```
如果該表已被創建,則可以使用 get_table 方法將一個表分配給一個變量:
```
hbase(main):011 > create 't','f'
0 row(s) in 1.2500 seconds
=> Hbase::Table - t
hbase(main):012:0> tab = get_table 't'
0 row(s) in 0.0010 seconds
=> Hbase::Table - t
hbase(main):013:0> tab.put 'r1' ,'f', 'v'
0 row(s) in 0.0100 seconds
hbase(main):014:0> tab.scan
ROW COLUMN+CELL
r1 column=f:, timestamp=1378473876949, value=v
1 row(s) in 0.0240 seconds
hbase(main):015:0>
```
列表功能也已被擴展,以便它返回一個表名稱作為字符串的列表。然后,您可以使用 jruby 根據這些名稱對表操作進行腳本編寫。list_snapshots 命令的作用也相似。
```
hbase(main):016 > tables = list('t.*')
TABLE
t
1 row(s) in 0.1040 seconds
=> #<#<Class:0x7677ce29>:0x21d377a4>
hbase(main):017:0> tables.map { |t| disable t ; drop t}
0 row(s) in 2.2510 seconds
=> [nil]
hbase(main):018:0>
```
### 20.2\. _irbrc_
在您的主目錄中為自己創建一個 _.irbrc_ 文件,添加自定義項。一個有用的是歷史記錄命令,因此命令可以跨 Shell 調用進行保存:
```
$ more .irbrc
require 'irb/ext/save-history'
IRB.conf[:SAVE_HISTORY] = 100
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-save-history"
```
如果您想避免將每個表達式的計算結果打印到 stderr,例如從“list”命令返回的表數組:
```
$ echo "IRB.conf[:ECHO] = false" >>~/.irbrc
```
請參閱 _.irbrc_ 的`ruby`文檔以了解其他可能的配置。
### 20.3\. LOG data to timestamp
要將日期'08/08/16 20:56:29'從 hbase 日志轉換為時間戳,請執行以下操作:
```
hbase(main):021:0> import java.text.SimpleDateFormat
hbase(main):022:0> import java.text.ParsePosition
hbase(main):023:0> SimpleDateFormat.new("yy/MM/dd HH:mm:ss").parse("08/08/16 20:56:29", ParsePosition.new(0)).getTime() => 1218920189000
```
相反
```
hbase(main):021:0> import java.util.Date
hbase(main):022:0> Date.new(1218920189000).toString() => "Sat Aug 16 20:56:29 UTC 2008"
```
以與 HBase 日志格式完全相同的格式輸出將會對[SimpleDateFormat](http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html) 產生一些影響。
### 20.4\. 查詢 Shell 配置
```
hbase(main):001:0> @shell.hbase.configuration.get("hbase.rpc.timeout")
=> "60000"
```
在 shell 中設置一個配置:
```
hbase(main):005:0> @shell.hbase.configuration.setInt("hbase.rpc.timeout", 61010)
hbase(main):006:0> @shell.hbase.configuration.get("hbase.rpc.timeout")
=> "61010"
```
### 20.5\. 使用 HBase Shell 預分割表
在通過 HBase Shell 的 `create` 命令創建表時,您可以使用各種選項預先拆分表。
最簡單的方法是在創建表格時指定一個分割點數組。請注意,當將字符串文字指定為分割點時,這些將根據字符串的基礎字節表示創建分割點。所以當指定分割點“10”時,我們實際上是指定了字節分割點“\x31\30”。
分割點將定義 `n+1 ` 區域,其中 `n` 是分割點的數量。最低的區域將包含從最低可能的鍵直到但不包括第一分割點密鑰的所有密鑰。下一個區域將包含從第一個分割點開始的密鑰,但不包括下一個分割點密鑰鍵。這將持續到最后的所有分界點。最后一個區域將從最后一個拆分點定義為最大可能的密鑰。
```
hbase>create 't1','f',SPLITS => ['10','20','30']
```
在上面的例子中,將使用列族 "f" 創建表 "t1",預先拆分到四個區域。請注意,第一個區域將包含從“\x00”到“\x30”(因為“\x31”是“1”的 ASCII 碼)的所有密鑰。
您可以使用以下變化將分割點傳遞到文件中。在這個例子中,分割是從對應于本地文件系統上的本地路徑的文件中讀取的。文件中的每一行都指定一個分割點密鑰。
```
hbase>create 't14','f',SPLITS_FILE=>'splits.txt'
```
其他選項是根據所需的區域數量和分割算法自動計算分割。HBase 提供基于統一拆分或基于十六進制密鑰分割密鑰范圍的算法,但您可以提供自己的拆分算法來細分密鑰范圍。
```
# 根據隨機字節鍵創建包含四個區域的表
hbase>create 't2','f1', { NUMREGIONS => 4 , SPLITALGO => 'UniformSplit' }
# 基于十六進制鍵創建具有五個區域的表
hbase>create 't3','f1', { NUMREGIONS => 5, SPLITALGO => 'HexStringSplit' }
```
由于 HBase Shell 實際上是一個 Ruby 環境,因此您可以使用簡單的 Ruby 腳本以算法方式計算分割。
```
# generate splits for long (Ruby fixnum) key range from start to end key
hbase(main):070:0> def gen_splits(start_key,end_key,num_regions)
hbase(main):071:1> results=[]
hbase(main):072:1> range=end_key-start_key
hbase(main):073:1> incr=(range/num_regions).floor
hbase(main):074:1> for i in 1 .. num_regions-1
hbase(main):075:2> results.push([i*incr+start_key].pack("N"))
hbase(main):076:2> end
hbase(main):077:1> return results
hbase(main):078:1> end
hbase(main):079:0>
hbase(main):080:0> splits=gen_splits(1,2000000,10)
=> ["\000\003\r@", "\000\006\032\177", "\000\t'\276", "\000\f4\375", "\000\017B<", "\000\022O{", "\000\025\\\272", "\000\030i\371", "\000\ew8"]
hbase(main):081:0> create 'test_splits','f',SPLITS=>splits
0 row(s) in 0.2670 seconds
=> Hbase::Table - test_splits
```
請注意,HBase Shell 命令 `truncate` 有效地刪除并重新創建具有默認選項的表格,這將丟棄任何預分割。如果您需要截斷預分割表,則必須顯式刪除并重新創建表以重新指定自定義分割選項。
### 20.6\. 調試
#### 20.6.1\. Shell 調試開關
您可以在 shell 中設置一個調試開關,以查看更多輸出 - 例如,運行命令時出現更多的異常堆棧跟蹤:
```
hbase> debug <RETURN>
```
#### 20.6.2\. DEBUG log level
要在 shell 中啟用 DEBUG 級日志記錄,請使用該 `-d` 選項啟動它:
```
$ ./bin/hbase shell -d
```
### 20.7\. 命令
#### 20.7.1\. count
Count 命令返回表中的行數。配置正確的 CACHE 時速度非常快:
```
hbase> count '<tablename>', CACHE => 1000
```
上述計數一次取 1000 行。如果行很大,請將 CACHE 設置得較低。默認是每次讀取一行。
- HBase? 中文參考指南 3.0
- Preface
- Getting Started
- Apache HBase Configuration
- Upgrading
- The Apache HBase Shell
- Data Model
- HBase and Schema Design
- RegionServer Sizing Rules of Thumb
- HBase and MapReduce
- Securing Apache HBase
- Architecture
- In-memory Compaction
- Backup and Restore
- Synchronous Replication
- Apache HBase APIs
- Apache HBase External APIs
- Thrift API and Filter Language
- HBase and Spark
- Apache HBase Coprocessors
- Apache HBase Performance Tuning
- Troubleshooting and Debugging Apache HBase
- Apache HBase Case Studies
- Apache HBase Operational Management
- Building and Developing Apache HBase
- Unit Testing HBase Applications
- Protobuf in HBase
- Procedure Framework (Pv2): HBASE-12439
- AMv2 Description for Devs
- ZooKeeper
- Community
- Appendix