本文最后更新于:2022-05-21T10:45:10+08:00
HBase Shell
HBase数据库默认的客户端程序是HBase
Shell,这是一个命令行工具,类似于MySQL客户端启动后出现的命令行Shell。在启动HBase集群之后(同时配置了环境变量),在命令行中输入hbase shell即可进入。
HBase
Shell是一个封装了Java客户端API的JRuby应用软件,其中提供的命令可以理解成为是Ruby函数的调用,每个命令都是一个Ruby脚本,后面跟着的参数为传入的参数,具体格式在后续进行说明。在下面链接中列出了在HBase
Shell中可用的所有脚本:
hbase/hbase-shell/src/main/ruby/shell/commands
at master · apache/hbase (github.com)
在 Shell
中输入help可以获取可用命令列表,输入help commandname可获取特定命令的帮助,还可以输入各种命令查看集群、数据库和数据的各项详情。
- 使用
status命令查看当前集群各节点的状态
- 使用
version命令查看当前 HBase 的版本号
- 使用命令
exit或quit即可退出 HBase
Shell
- 使用
whoami命令显示当前用户
HBase
Shell提供的命令可以大致分为两类,一类是对数据表的管理命令,包括对表的创建,禁用,删除等操作;另一类是对表中数据的增删改查命令。
数据表管理命令
常用命令汇总:
| create |
创建指定模式的新表 |
| alter |
修改表的结构,如添加新的列族等 |
| describe |
展示表结构信息,包括列族的数量与属性等 |
| list |
列出HBase中已有的表 |
| exists |
判断某个表是否存在 |
| disable / enable |
禁用 /
解禁一个表。在删除和更改表之前,需要禁用这个表 |
| disable_all |
禁用所有的表,可以使用正则表达式匹配 |
| is_disable |
判断一个表是否被禁用 |
| drop |
删除表 |
| truncate |
删除表中数据。truncate可以禁用表、删除表并自动重建表结构 |
命令使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| # 创建表: 使用create命令,需要指明表名,列族名 create "MY_TABLE", "C1", "C2"
# 修改表: 使用alter命令,指定表名以及需要做什么样的修改 # 改变列族C1的版本保存数目 alter "MY_TABLE", {NAME => "C1", VERSION => 6}
# 增加列族C3 alter "MY_TABLE", "C3"
# 删除列族C3,下面两种方式都可以(HBase表中至少要包含一个列族,当表中只有一个列族的时候,无法将其删除) alter "MY_TABLE", "delete" => "C3" alter "MY_TABLE", {NAME => "C3", METHOD => "delete"}
# 删除表: 首先需要禁用表,然后才能删除 disable "MY_TABLE" drop "MY_TABLE"
# 清空表中的数据,相当于禁用表,删除表,按照原结构重建表 truncate "MY_TABLE"
|
前面提到HBase
Shell命令都是Ruby脚本,可以理解为对Ruby函数的调用,不同的函数传入参数的形式不同。传入引号包裹的字符串就是传入字符串;传入{}包裹的参数,表示传入一个类似Map的结构,其中Map的每一个键值对有key => value的格式,key一般是给定的参数,不使用引号标识;传入[]包裹的参数,表示传入一个类似数组的结构
增删改查命令
常用命令汇总:
| put |
添加一个值到指定单元格中 |
| get |
通过表名、行键等参数获取行或者单元格的数据 |
| scan |
遍历表并输出满足指定条件的行记录 |
| count |
计算表中的逻辑行数(会遍历所有的存储数据,谨慎使用) |
| delete |
删除表中列族或者列的数据 |
| deleteall |
删除逻辑行 |
命令使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| # 添加数据: 使用put命令,但是每次只能保存一个列的值 # put命令需要指定表名, 行键, 列族名:列标识符, 值, [时间戳] # 时间戳是可选项,如果没有显式指定,则系统自动插入当前时间戳 put "MY_TABLE", "000001", "C1:Name", "test"
# 更新数据,同样使用put命令
# 查看数据: 使用get命令,可以获取行或者单元格的数据 # 表名,行键获取一行的数据 # 表名,行键,列族名:列标识符 获取单元格的数据 # 中文的显示 {FORMATTER => 'toString'} get "MY_TABLE", "000001" get "MY_TABLE", "000001", "C1:Name", {FORMATTER => 'toString'}
# 查看全表,使用scan命令 scan "MY_TABLE"
# 限制查询数目 scan "MY_TABLE", {LIMIT => 3, FORMATTER => 'toString'}
# 指定查询的列 scan "MYTABLE", {COLUMNS => ['C1:Name','C2:Address']}
# 指定查询的行键 scan "MY_TABLE", {ROWPREFIXFILTER => '000001'}
# 删除数据 # 删除某一个单元格的数据,使用delete delete "MY_TABLE", "000001", "C1:Name" # delete无法跨列族操作,如果要删除一个逻辑行,需要使用deleteall命令 deleteall "MY_TABLE", "000001"
|
需要注意的是,delete操作并不会马上删除数据,只会将对应的数据打上删除标记,在空闲合并数据的时候,数据才会被删除。同时delete删除的是最新版本的数据。
HBase过滤器
在HBase中,get和scan操作可以使用过滤器来设置输出的范围,增加查询的条件,类似于SQL里面的where条件。在HBase
Shell中使用show_filter命令可以查看当前HBase支持的过滤器类型。过滤器的实现使用的是Java,HBase
Shell命令相当于封装了一层进行API的调用。
过滤器的语法格式如下:
1
| scan "表名", {FILTER => "过滤器(比较运算符, '比较器表达式')"}
|
- 过滤器表示过滤的层次,如行键过滤器、列族过滤器等
- 比较运算符即表示判断逻辑,如等于,大于,小于等
- 比较器表达式表示进行比较的值,如匹配完整字节数组,匹配子字符串等
过滤器可以在官方API中找到 org.apache.hadoop.hbase.filter
(Apache HBase 3.0.0-alpha-3-SNAPSHOT API)
。所在包为package org.apache.hadoop.hbase.filter
比较运算符:=、>、<、>=、<=、!=
比较器:
| BinaryComparator |
binary:value |
匹配完整字节数组 |
| BinaryPrefixComparator |
binaryprefix:value |
匹配字节数组前缀 |
| BitComparator |
bit:value |
匹配比特位 |
| NullComparator |
null |
匹配空值 |
| RegexStringComparator |
regexstring:正则表达式 |
匹配正则表达式 |
| SubstringComparator |
substring:value |
匹配子字符串 |
并且如果需要使用多个过滤器共同来实现查询,可以使用AND或者OR来组合多个过滤器来完成查询
但是需要注意的是,在HBase
Shell中默认都是字符串比较,如果比较数值类型,可能会出现不准确的情况。
下面介绍一些常用的过滤器以及对应的使用方法。
行键过滤器
行键过滤器,RowFilter,可以实现对行键字符串的比较和过滤。
1 2 3 4 5
| # 如果行键是1234的子字符串,则匹配 scan "MY_TABLE", {FILTER => "RowFilter(=, 'substring:1234')"}
# 如果行键大于hahaha(字符串顺序),则匹配 scan "MY_TABLE", {FILTER => "RowFilter(>, 'binary:hahaha')"}
|
其他行键过滤器描述:
| PrefixFilter |
行键前缀比较器 |
| KeyOnlyFilter |
只显示单元格的键(列族名:列标识符),不显示值 |
| FirstKeyOnlyFilter |
对于每一行,只显示第一个单元格 |
| InclusiveStopFilter |
指定终止条件行 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| # PrefixFilter # 下面两种方式等价, PrefixFilter无需结合运算符和比较器 scan "MY_TABLE", {FILTER => "PrefixFilter('0001')"} scan "MY_TABLE", {FILTER => "RowFilter(=, 'binaryprefix:0001')"}
# KeyOnlyFilter scan "MY_TABLE", {FILTER => "KeyOnlyFilter()"}
# FirstKeyOnlyFilter scan "MY_TABLE", {FILTER => "FirstKeyOnlyFilter()"}
# InclusiveStopFilter # 下面两种方式等价 scan "MY_TABLE", {STARTROW => '0001', FILTER => "InclusiveStopFilter('binary:0002')"} scan "MY_TABLE", {STARTROW => '0001', ENDROW => '0003'}
|
列族与列过滤器
列族过滤器,FamilyFilter,根据列族字符串进行比较和过滤
1 2
| # 匹配所有列族为C1的单元格 scan "MY_TABLE", {FILTER => "FamilyFilter(=, 'binary:C1')"}
|
其他列过滤器描述:
| QualifierFilter |
列标识符过滤器,根据列标识符进行过滤 |
| ColumnPrefixFilter |
对列标识符前缀进行过滤 |
| MultipleColumnPrefixFilter |
可以指定多个前缀对列标识符进行过滤 |
| ColumnRangeFilter |
过滤列标识符名称的范围,指定区间,同时可以指定区间开闭 |
1 2 3 4 5 6 7 8 9 10 11 12 13
| # QualifierFilter scan "MY_TABLE", {FILTER => "QualifierFilter(=, 'binary:Math')"}
# ColumnPrefixFilter # ColumnPrefixFilter无需结合运算符和比较器 scan "MY_TABLE", {FILTER => "ColumnPrefixFilter('Ma')"}
# MultipleColumnPrefixFilter scan "MY_TABLE", {FILTER => "MultipleColumnPrefixFilter('Ma', 'Ag')"}
# ColumnRangeFilter # 下面命令指定为左开右闭 scan "MY_TABLE", {FILTER => "ColumnRangeFilter('Big', ture, 'Math', false)"}
|
值过滤器
值过滤器按照单元格的值进行匹配和过滤。
| ValueFilter |
值过滤器,根据单元格中的值找到符合条件的键值对 |
| SingleColumnValueFilter |
指定对应列族和列,按照定位到的值进行比较 |
| SingleColumnValueExcludeFilter |
排除匹配成功的值,与上一个过滤器的扫描结果相反 |
1 2 3 4 5 6 7 8 9 10
| # ValueFilter,匹配所有值为haha的单元格 scan "MY_TABLE", {FILTER => "ValueFilter(=, 'binary:haha')"}
# SingleColumnValueFilter,指定列族,列标识符,比较运算符,比较器 # 匹配所有C1:Name项值为haha的单元格 scan "MY_TABLE", {FILTER => "SingleColumnValueFilter('C1', 'Name', =, 'binary:haha')"}
# SingleColumnValueExcludeFilter # SingleColumnValueFilter的反向匹配 scan "MY_TABLE", {FILTER => "SingleColumnValueExcludeFilter('C1', 'Name', =, 'binary:haha')"}
|
其他过滤器
| ColumnCountGetFilter |
限制每个逻辑行中返回键值对的个数 |
| TimestampsFilter |
根据时间戳进行过滤,可以同时设置多个时间戳 |
| InclusiveStopFilter |
设置停止行,扫描到对应行就停止扫描 |
| PageFilter |
对显示结果按行进行分页显示 |
| ColumnPaginationFilter |
对一个逻辑行内的所有列进行分页,返回[offset,
offset+limit]范围内的列 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| # ColumnCountGetFilter get "MY_TABLE", {FILTER => "ColumnCountGetFilter(3)"}
# TimestampsFilter scan "MY_TABLE", {FILTER => "TimestampsFilter(1, 3)"}
# InclusiveStopFilter scan "MY_TABLE", {STARTROW => '0001', ENDROW => '0005', FILTER => "InclusiveStopFilter('0003')"}
# PageFilter scan "MY_TABLE", {STARTROW => '0001', ENDROW => '0005', FILTER => "PageFilter(3)"}
# ColumnPaginationFilter scan "MY_TABLE", {STARTROW => '0001', ENDROW => '0005', FILTER => "ColumnPaginationFilter(2, 1)"}
|
其他操作
数据上传与导出
我们可以通过一个txt文件来完成数据的上传,在这个txt文件中每一行都是一条能够在HBase
Shell中执行的命令。我们可以在HBase
Shell之外,在Linux命令行中执行下面的命令,将txt文件中的命令一次全部执行。这一过程类似于MySQL中对.sql文件的source操作
1
| hbase shell [txt文件在Linux文件系统中的位置]
|
还可以使用提供的MapReduce程序进行数据上传,在HBase中提供了一个用于Import的MapReduce作业,专门用来将数据文件导入到HBase中,用法如下:
1
| hbase org.apache.hadoop.hbase.mapreduce.Import 表名 HDFS数据文件路径
|
对应还存在一个数据导出的MapReduce程序:
1
| hbase org.apache.hadoop.hbase.mapreduce.Export 表名 HDFS输出路径
|
大量数据的计数统计
当HBase中数据量大的时候,可以使用HBase中提供的MapReduce程序来进行计数统计,语法如下:
1
| $HBASE_HOME/bin/hbase org.apache.hadoop.hbase.mapreduce.RowCounter "表名"
|
incr
incr可以实现对某个单元格的值进行原子性计数,语法如下:
1
| incr "表名", "rowkey", "列族:列标识符", [累加值,默认为1]
|
如果某一列需要实现计数功能,必须使用incr来创建对应的列,使用put创建的列是不能实现累加功能的。
对于incr创建的列,需要使用get_counter来访问,格式与get命令类似。
参考文章
- HBase过滤器入门教程