HBase表管理
HBase的表管理对应于前面提到的DDL命令,它定义了对表及其结构的操作,包括表的创建、结构修改、表的停用、表的删除、批量停用与删除表等。
主要内容包括:
- 从Shell创建HBase表
- 列表显示HBase表
- 描述表信息
- 使用put命令向HBase表插入数据
- 通过HBase Shell验证表是否存在
- 通过HBase Shell统计表记录数量
- 使用HBase Shell从HBase表中读取(扫描)Rows
- 使用Scan读取数据时指定过滤器
- 用HBase shell从表中获取单个行和特定列
- 使用HBase Shell禁用和启用表
- 删除HBase表中的行
HBase将行存储在表中,每个表被划分为“region”。这些region分布在集群中,由系统中的RegionServer进程托管并提供给客户端进程使用。表中的所有行在region开始键和结束键之间排序。每一行都恰好属于一个region,而一个region在任何给定的时间点都由单个region server提供服务
从Shell创建HBase表
使用create命令能够创建一张HBase表,需要指定的参数包括命名空间、表名称、列族名称。
创建HBase表的语法如下所示:
CREATE 'name_space:table_name', 'column_family'
注意,表名的命名空间是可选的,如果没有指定,它会在默认命名空间(default)中创建一个表。而column_family是强制性的,至少需要一个列族才能成功创建表。如果未指定,则返回一个错误。
下面的示例在default命名空间中创建一个“emp”表,并将列族设置为“office”。
hbase> CREATE 'emp', 'office'
当试图使用已经存在的名称创建一个表时,无论列族是否相同,都将得到错误消息。一个命名空间中的HBase表应该是唯一的。
HBase分割表
HBase表被分割并将数据存储到几个region中。表创建时,HBase默认只分配一个region给它。让我们看看如何将表划分为多个区域并有效地使用集群的示例。
HBase分割表语法如下所示:
CREATE 'name_space:table_name', 'column_family' SPLITS => ['10', '20', '30', '40']
下面的示例代码创建了一个新的表dep:
hbase> CREATE 'dep', 'office', SPLITS => ['10', '20', '30']
当创建表时,还可以指定许多选项,请参考HBase Shell命令速查-DDL命令
列表显示HBase表
使用list命令显示HBase中所有的用户表。列表还支持可选的正则表达式来过滤输出。列表的语法如下所示。
list '<namespace>:<regular expression>'
要显示所有表,只需使用不带任何参数的list命令。当表属于一个名称空间时,结果上将显示名称空间。
使用list命令可列出所有的表:
hbase> list
另外,还可以使用表名和限定名称空间。当没有找到表时,它返回0行。
使用正则表达式过滤列表结果
如果您想过滤结果,可以使用正则表达式,如下所示:
hbase> list '.*mp.*'
描述表信息
可以使用describe命令描述HBase表的详细信息和配置。例如,版本、压缩、块大小、复制等等。描述表的语法如下。
describe <'namespace':'table_name'>
例如,查看表emp的详细信息和配置:
hbase> describe 'emp'
在命名空间中创建表时,需要通过命令对其进行限定。在上面的示例中,我们没有限定名称空间。
describe命令还将返回表的启用或禁用状态。
使用put命令向HBase表插入数据
使用PUT命令向HBase表的行和列插入数据。这类似于RDBMS上的插入语句,但是语法完全不同。
下面是PUT命令的语法,用于向HBase表中插入数据(行和列)。
put '<name_space:table_name>', '<row_key>' '<cf:column_name>', '<value>'
下面是一些向HBase表emp插入数据的示例。
hbase> put 'emp', '1' , 'office:name', 'Scott' hbase> put 'emp', '2' , 'office:name', 'Mark' hbase> put 'emp', '2' , 'office:gender', 'M' hbase> put 'emp', '2' , 'office:age', '30' hbase> put 'emp', '2' , 'office:age', '50'
在上面的例子中,注意我们添加了2行;行键“1”有一列“office:name”,行键“2”有三列“office:name”,“office:gender”和“office:age”。
另外,请注意,上面示例中的最后一个命令实际上在行键“2”上用“50”插入了一个新列“office:age”。在内部,HBase不做更新,但它分配一个带有新的时间戳的列,并且扫描时从列中获取最新的数据。
下面添加插入更多的行:
hbase> put 'emp', '3', 'office:salary', '10000' hbase> put 'emp', '3', 'office:name', 'Jeff' hbase> put 'emp', '3', 'office:salary', '20000' hbase> put 'emp', '3', 'office:salary', '30000' hbase> put 'emp', '3', 'office:salary', '40000' hbase> put 'emp','1','office:age','20' hbase> put 'emp','3','office:age','30'
通过HBase Shell验证表是否存在
使用exists命令验证数据库中是否存在指定的表。其语法如下:
exists '<namespace>:<table_name>'
例如,判断HBase数据库中是否存在emp表:
hbase> exists 'emp' hbase> exists 'emp123'
执行exists将与消息一起返回布尔值。当表存在于数据库中时返回'true',当表在数据库中不存在时返回' false '。。
通过HBase Shell统计表记录数量
使用count命令获取表中的总记录。其语法如下:
count '<namespace>:<table_name>'
例如,统计表emp中记录数:
hbase> count 'emp'
执行这个命令,会返回表中的行数。
当表不存在时,该方法会返回"Unknown table"。
使用HBase Shell从HBase表中读取(扫描)Rows
使用scan命令从HBase表中获取数据。默认情况下,它从表中获取所有数据。例如:
hbase> scan 'emp'
我们可以通过传入扫描器规范limit来限制结果。下面的示例限制为一行。
hbase> scan 'emp', {LIMIT => 1}
下面的命令限制查询的结果为2行"1"和"2":
hbase> scan 'emp', {LIMIT => 2}
使用COLUMN规范,我们可以列出具有指定有列的行。例如:
hbase> scan 'emp', {LIMIT => 2, COLUMN => ['office:name']}
下面的命令返回具有'name'和'age'列的两行记录:
hbase> scan 'emp', {LIMIT => 2, COLUMNS => ['office:name','office:age']}
我们还可以指定STARTROW,结果从这里返回:
hbase> scan 'emp', {LIMIT => 2, COLUMNS => ['office:name','office:age'], STARTROW => '2'}
也可以指定STOPROW规范,指定到哪里停止:
hbase> scan 'emp', {COLUMNS => ['office:name','office:age'], STARTROW => '1', STOPROW => '3'}
要列出所有已删除的列,需要使用RAW选项:
hbase> scan 'emp', {RAW => true}
下面是更多的scan命令使用示例:
hbase> scan 'hbase:meta' hbase> scan 'hbase:meta', {COLUMNS => 'info:regioninfo'} hbase> scan 'ns1:t1', {COLUMNS => ['c1','c2'], LIMIT => 10, STARTROW => 'xyz'} hbase> scan 't1', {COLUMNS => ['c1','c2'], LIMIT => 10, STARTROW => 'xyz'} hbase> scan 't1', {COLUMNS => 'c1', TIMERANGE => [1303668804000, 1303668904000]} hbase> scan 't1', {REVERSED => true} hbase> scan 't1', {ALL_METRICS => true} hbase> scan 't1', {METRICS => ['RPC_RETRIES','ROWS_FILTERED']} hbase> scan 't1', {ROWPREFIXFILTER => 'row2', FILTER => "(QualifierFilter(>=, 'binary:xyz')) AND (TimestampsFilter(123,456))"} hbase> scan 't1', {FILTER => org.apache.hadoop.hbase.filter.ColumnPaginationFilter.new(1,0)} hbase> scan 't1', {CONSISTENCY => 'TIMELINE'} hbase> scan 't1', {ISOLATION_LEVEL => 'READ_UNCOMMITTED'} hbase> scan 't1', {MAX_RESULT_SIZE => 123456} # 设置运算属性 hbase> scan 't1', {COLUMNS => ['c1','c2'], ATTRIBUTES => {'mykey' => 'myvalue'}} hbase> scan 't1', {COLUMNS => ['c1','c2'], AUTHORIZATIONS => ['PRIVATE', 'SECRET']} # 对于专家来说,还有一个额外的选项--CACHE_BLOCKS--用于scanner的块缓存切换开关,默认是enabled hbase> scan 't1', {COLUMNS => ['c1','c2'], CACHE_BLOCKS => false}
使用Scan读取数据时指定过滤器
在使用HBase Scan时,我们可以在列上使用类似于SQL中的WHERE子句的谓词条件来过滤表中的行/记录。为了使用过滤器,需要在HBase Shell中导入一些Java类。
SingleColumnValueFilter
为了使用Scan在HBase shell上过滤行,需要导入org.apache.hadoop.hbase.filter.SingleColumnValueFilter类以及下面解释的一些其他类。
hbase> import org.apache.hadoop.hbase.filter.SingleColumnValueFilter hbase> import org.apache.hadoop.hbase.filter.CompareFilter hbase> import org.apache.hadoop.hbase.filter.BinaryComparator
示例1:返回name=='Jeff'的行:
hbase> scan 'emp', { FILTER => SingleColumnValueFilter.new(Bytes.toBytes('office'), Bytes.toBytes('name'), CompareFilter::CompareOp.valueOf('EQUAL'),BinaryComparator.new(Bytes.toBytes('Jeff')))}
执行以上命令,返回内容如下:
ROW COLUMN+CELL 3 column=office:age, timestamp=1567542149583, value=30 3 column=office:name, timestamp=1567542103821, value=Jeff 3 column=office:salary, timestamp=1567542130044, value=40000 1 row(s) Took 0.0480 seconds
示例2:返回年龄不小于50的行:
hbase> scan 'emp', { FILTER => SingleColumnValueFilter.new(Bytes.toBytes('office'), Bytes.toBytes('age'), CompareFilter::CompareOp.valueOf('GREATER_OR_EQUAL'),BinaryComparator.new(Bytes.toBytes('50')))}
执行以上命令,返回内容如下:
ROW COLUMN+CELL 2 column=office:age, timestamp=1567541901009, value=50 2 column=office:gender, timestamp=1567541880523, value=M 2 column=office:name, timestamp=1567541868638, value=Mark 1 row(s) Took 0.0180 seconds
示例3:返回列值等于40000的行:
hbase> scan 'emp', {FILTER => "ValueFilter (=,'binaryprefix:40000')"}
执行以上命令,返回内容如下:
ROW COLUMN+CELL 3 column=office:salary, timestamp=1567542130044, value=40000 1 row(s) Took 0.0034 seconds
用HBase shell从表中获取单个行和特定列
使用get从单行及其列中检索数据。命令get的语法如下所示。
get '<namespace>:<table_name>', '<row_key>', '<column_key>'
示例:下面的命令返回行键为'2'的行及其所有列:
hbase> get 'emp','2'
示例:下面的命令返回行键为'2'的行及其'office:age'列和'office:name'列。
hbase> get 'emp','2', 'office:age', 'office:name'
或者,使用下面的命令,返回相同的结果:
hbase> get 'emp','2', {COLUMNS => ['office:age', 'office:name']}
更多get命令使用示例如下:
hbase> get 'ns1:t1','r1' hbase> get 't1','r1',{TIMERANGE => [ts1, ts2]} hbase> get 't1','r1',{COLUMN => 'c1'} hbase> get 't1','r1',{COLUMN => ['c1','c2','c3']} hbase> get 't1','r1',{COLUMN => 'c1', TIMESTAMP => ts1} hbase> get 't1','r1',{COLUMN => 'c1', TIMERANGE => [ts1, ts2], VERSIONS => 4} hbase> get 't1','r1',{COLUMN => 'c1', TIMESTAMP => ts1, VERSIONS => 4} hbase> get 't1','r1',{FILTER => "ValueFilter(=, 'binary:abc')"} hbase> get 't1','r1', 'c1' hbase> get 't1','r1', 'c1', 'c2' hbase> get 't1','r1', ['c1', 'c2'] hbase> get 't1','r1',{COLUMN => 'c1', ATTRIBUTES => {'mykey' => 'myvalue'}} hbase> get 't1','r1',{COLUMN => 'c1', AUTHORIZATIONS => ['PRIVATE','SECRET']} hbase> get 't1','r1',{CONSISTENCY => 'TIMELINE'} hbase> get 't1','r1',{CONSISTENCY => 'TIMELINE', REGION_REPLICA_ID => 1}
使用HBase Shell禁用和启用表
我们可以使用HBase shell禁用和启用现有的HBase表。
禁用表
使用'disable'禁用一个表。在删除表或更改其设置之前,首先需要禁用该表。禁用表的语法如下所示。
disable '<namespace>:<table_name>'
例如,要禁用表'emp':
hbase> disable 'emp'
使用is_disabled检查表是否被禁用。当表被禁用时它会返回"true":
hbase> is_disabled 'emp'
还要以使用describe来查看表的描述信息,在描述信息中包含了该表是否被禁用的信息。
hbase> describe 'emp'
一旦该表被禁用,就不能执行常规的操作命令。
启用表
使用'enalbe'来启用一个被禁用的表。需要首先启用一个被禁用的表来执行任何常规命令。启用表的语法如下。
hbase> enable '<namespace>:<table_name>'
例如,要启用之前被禁用的'emp'表:
hbase> enable 'emp'
使用describe命令查看该表是否被启用:
hbase> describe 'emp'
删除HBase表中的行
我们可以使用delete和deleteall命令从HBase表中删除整行和一行的特定列单元格。
使用deleteall命令
使用deleteall命令从HBase表中删除指定的行。它将表名和行作为强制参数,列和时间戳作为可选参数。它还支持使用行键前缀删除行范围。deleteall的语法如下所示。
deleteall '<table_name>', 'row_key', '<column_name>'
例如,要从表'emp'中删除行'1'及其所有单元格。
hbase> deleteall 'emp', '1'
示例:从row '2'中删除所有单元'office:age'
hbase> deleteall 'emp', '2', 'office:age'
运行scan命令扫描表不会获取删除的行和列。
使用CACHE选项,指定一次要发送多少批数据到服务器,这主要用于处理较大的数据集。当未指定时,默认为100。
hbase> deleteall 'emp', {CACHE => 100}
更多deleteall的示例如下所示:
hbase> deleteall 't1','r1','c1', ts1 hbase> deleteall 't1','r1','c1', ts1, {VISIBILITY => 'PRIVATE|SECRET'} hbase> deleteall 't1',{ROWPREFIXFILTER => 'prefix'} hbase> deleteall 't1',{ROWPREFIXFILTER => 'prefix'}, 'c1' hbase> deleteall 't1',{ROWPREFIXFILTER => 'prefix'}, 'c1', ts1 hbase> deleteall 't1',{ROWPREFIXFILTER => 'prefix'}, 'c1', ts1, {VISIBILITY => 'PRIVATE|SECRET'} hbase> deleteall 't1',{ROWPREFIXFILTER => 'prefix', CACHE => 100}
使用delete命令
使用delete命令从表中删除一行中的一列。与deleteall不同,delete命令将'column cell'作为表和行键的强制参数。可以选择使用时间戳。
delete的语法如下。
delete '<table_name>', 'row_key', '<column_name>'
例如:从't1'表的'r1'行删除时间戳为'ts1'的'c1'单元格:
hbase> delete 't1', 'r1', 'c1', ts1
示例:
hbase> delete 't1', 'r1', 'c1', ts1, {VISIBILITY=>'PRIVATE|SECRET'}