HBase Shell命令的使用一
用过Mysql的同学,都知道mysql 有一个命令行工具,我们可以进入MySql的命令行,执行命令,如下图:
HBase和Mysql类似也有一个命令行工具,这个工具叫做HBase Shell。
Apache HBase Shell 是 也是一个 HBase 命令行工具。
Apache HBase Shell的安装
如果你学习了docker快速安装HBase这一课,那么你已经能刚进入shell中了,我们先使用这种方式进入shell,等熟练后,我们再解释其他安装方式。
HBase Shell的初次使用
HBase shell是一个命令行程序,如果你在windows上,通过cmd打开命令行,如果你在mac上,通过terminal打开命令行。
然后定位到 HBase的bin目录下,执行如下操作:
$ ./bin/hbase shell
这样就启动 hbase shell了。如下图:
help命令
我们一开始接触Hbase当然不知道有什么命令,更别提每个命令是什么意思了,所以需要输入:help
,然后按 <RETURN>
查看 shell 命令和选项的列表。
help
通过help命令能看到所有的hbase支持的命令。都是英文的,对英文不太好的同学,会有一些不方便,我们将所有的Hbase Shell命令写到了另一篇文章,大家可以参考hbase-shell-commands
系统脚本中的 HBase Shell
您可以在操作系统脚本解释器中使用 HBase shell,例如 Bash shell,它是大多数 Linux 和 UNIX 发行版的默认命令解释程序。以下准则使用 Bash 语法,但可以调整为使用 C 样式的 shell(例如 csh 或 tcsh),并且可能会修改为使用 Microsoft Windows 脚本解释器一起使用。
这种方式生成 HBase Shell 命令的速度很慢,所以在决定何时将 HBase 操作与操作系统命令行相结合时,请记住这一点。
一些操作shell的例子: 传递命令到 HBase Shell
我们先来学习一些例子:
您可以使用 echo
命令和 |
(管道)操作,以非交互模式将命令传递数据到 HBase Shell中。 一定要转义 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
这里是查看test1表的结构。如果没有这个表,会显示表不存在。
上面的脚本等价于,先进入hbase shell,然后执行:
describe 'test1'
若要取消所有输出,请将其回显到 /dev/null:
$ echo "describe 'test'" | ./hbase shell -n > /dev/null 2>&1
例子:检查脚本命令的返回结果
由于脚本不是设计为交互式运行的,因此您需要一种方法来检查命令是失败还是成功。HBase shell 使用为成功的命令返回值0
的标准约定,并为失败的命令返回一些非零值。
Bash 将命令的返回值存储在一个名为 $?
的特殊环境变量中。因为每次 shell 运行任何命令时都会覆盖该变量,所以应该将结果存储在另一个脚本定义的变量中。
下面的这个脚本把$?赋值给status变量。
#!/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
这段代码,查询hbase中时候有test这个表,由于我们并没有建立这个表,所以status的值为1,表示执行错误。
如果有test这个表,那么status的返回值为0。
在脚本中检查成功或失败
获取退出代码0
意味着您脚本编写的命令确实成功了。但是,获取非零退出代码并不一定意味着命令失败。该命令可能已成功,但客户端失去连接,或者其他事件阻碍了其成功。这是因为 RPC 命令是无状态的。确保操作状态的唯一方法是检查。例如,如果你的脚本创建一个表,但返回一个非零的退出值,你应该检查表是否实际创建,然后再试图创建它。
从命令文件读取 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'
指示 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
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.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 产生一些影响。
查询 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"
使用 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
有效地删除并重新创建具有默认选项的表格,这将丢弃任何预分割。如果您需要截断预分割表,则必须显式删除并重新创建表以重新指定自定义分割选项。