前言

提示:本博客为博主在阅读吴章勇和王强老师编写的《大数据 Hadoop3.X 分布式处理实战》的过程中,参照图书和个人理解进行HBase Shell的实验总结,算是该部分的读书笔记吧,当然本文对刚刚部署好HBase,还不了解HBase Shell的同学有一定的借鉴意义。


一、HBase Shell是什么?

前提知识1:Hbase是NoSQL数据库的一种,其建立在HDFS上,有【高可靠、高性能、列式存储,可伸缩】的特点,能通过增加节点的方式简单地达到线性扩容的目的,是hadoop生态圈中用于分布式存储的一个重要组件。

前提知识2:结构化查询语言SQL的应用场景是传统关系型数据库,其存储的数据是结构化的;NoSQL数据库不支持结构化查询语言SQL,而HBase是一种比较特殊的NoSQL数据库,能存储结构化数据、半结构化数据、非结构化数据,但是主要存储非结构化数据和半节构化数据;仅能通过主键和主键的范围来检索数据,仅支持单行事物。

HBase允许类似shell的命令来操作HBase数据库,这些命令的解释器就被称之为HBase Shell,通过这些命令用户可以方便地创建、删除及修改表,还可以向表中添加数据、列出表中相关信息等。学习过spark的同学可以类比spark-shell,虽然两者的命令风格不太一样,但是功能都是一样的——给用户提供了一个在命令行操作Spark/HBase的接口。

可以在HBase Shell界面输入help来列出来所以都HBase Shell命令:

hbase:001:0> help

得到的结果如下所示,包含了HBase的版本号,HBase的所有命令,这些命令被分成了general、ddl、namespace等十几个大类,此外也简单介绍了HBase命令的用法。

HBase Shell, version 2.4.1, rb4d9639f66fccdb45fea0244202ffbd755341260, Fri Jan 15 10:58:57 PST 2021
Type 'help "COMMAND"', (e.g. 'help "get"' -- the quotes are necessary) for help on a specific command.
Commands are grouped. Type 'help "COMMAND_GROUP"', (e.g. 'help "general"') for help on a command group.

COMMAND GROUPS:
  Group name: general
  Commands: processlist, status, table_help, version, whoami

  Group name: ddl
  Commands: alter, alter_async, alter_status, clone_table_schema, create, describe, disable, disable_all, drop, drop_all, enable, enable_all, exists, get_table, is_disabled, is_enabled, list, list_regions, locate_region, show_filters

  Group name: namespace
  Commands: alter_namespace, create_namespace, describe_namespace, drop_namespace, list_namespace, list_namespace_tables

  Group name: dml
  Commands: append, count, delete, deleteall, get, get_counter, get_splits, incr, put, scan, truncate, truncate_preserve

  Group name: tools
  Commands: assign, balance_switch, balancer, balancer_enabled, catalogjanitor_enabled, catalogjanitor_run, catalogjanitor_switch, cleaner_chore_enabled, cleaner_chore_run, cleaner_chore_switch, clear_block_cache, clear_compaction_queues, clear_deadservers, clear_slowlog_responses, close_region, compact, compact_rs, compaction_state, compaction_switch, decommission_regionservers, flush, get_balancer_decisions, get_largelog_responses, get_slowlog_responses, hbck_chore_run, is_in_maintenance_mode, list_deadservers, list_decommissioned_regionservers, major_compact, merge_region, move, normalize, normalizer_enabled, normalizer_switch, recommission_regionserver, regioninfo, rit, snapshot_cleanup_enabled, snapshot_cleanup_switch, split, splitormerge_enabled, splitormerge_switch, stop_master, stop_regionserver, trace, unassign, wal_roll, zk_dump

  Group name: replication
  Commands: add_peer, append_peer_exclude_namespaces, append_peer_exclude_tableCFs, append_peer_namespaces, append_peer_tableCFs, disable_peer, disable_table_replication, enable_peer, enable_table_replication, get_peer_config, list_peer_configs, list_peers, list_replicated_tables, remove_peer, remove_peer_exclude_namespaces, remove_peer_exclude_tableCFs, remove_peer_namespaces, remove_peer_tableCFs, set_peer_bandwidth, set_peer_exclude_namespaces, set_peer_exclude_tableCFs, set_peer_namespaces, set_peer_replicate_all, set_peer_serial, set_peer_tableCFs, show_peer_tableCFs, update_peer_config

  Group name: snapshots
  Commands: clone_snapshot, delete_all_snapshot, delete_snapshot, delete_table_snapshots, list_snapshots, list_table_snapshots, restore_snapshot, snapshot

  Group name: configuration
  Commands: update_all_config, update_config

  Group name: quotas
  Commands: disable_exceed_throttle_quota, disable_rpc_throttle, enable_exceed_throttle_quota, enable_rpc_throttle, list_quota_snapshots, list_quota_table_sizes, list_quotas, list_snapshot_sizes, set_quota

  Group name: security
  Commands: grant, list_security_capabilities, revoke, user_permission

  Group name: procedures
  Commands: list_locks, list_procedures

  Group name: visibility labels
  Commands: add_labels, clear_auths, get_auths, list_labels, set_auths, set_visibility

  Group name: rsgroup
  Commands: add_rsgroup, alter_rsgroup_config, balance_rsgroup, get_rsgroup, get_server_rsgroup, get_table_rsgroup, list_rsgroups, move_namespaces_rsgroup, move_servers_namespaces_rsgroup, move_servers_rsgroup, move_servers_tables_rsgroup, move_tables_rsgroup, remove_rsgroup, remove_servers_rsgroup, rename_rsgroup, show_rsgroup_config

SHELL USAGE:
Quote all names in HBase Shell such as table and column names.  Commas delimit
command parameters.  Type <RETURN> after entering a command to run it.
Dictionaries of configuration used in the creation and alteration of tables are
Ruby Hashes. They look like this:

  {'key1' => 'value1', 'key2' => 'value2', ...}

and are opened and closed with curley-braces.  Key/values are delimited by the
'=>' character combination.  Usually keys are predefined constants such as
NAME, VERSIONS, COMPRESSION, etc.  Constants do not need to be quoted.  Type
'Object.constants' to see a (messy) list of all constants in the environment.

If you are using binary keys or values and need to enter them in the shell, use
double-quote'd hexadecimal representation. For example:

  hbase> get 't1', "key\x03\x3f\xcd"
  hbase> get 't1', "key\003\023\011"
  hbase> put 't1', "test\xef\xff", 'f1:', "\x01\x33\x40"

The HBase shell is the (J)Ruby IRB with the above HBase-specific commands added.
For more on the HBase Shell, see http://hbase.apache.org/book.html

二、HBase Shell使用步骤

提示:使用HBase Shell之前需要部署好HBase,该部分的内容读者可以参考其他博文。值得一提的是:因为HBase是建立在HDFS上的,所以在部署HBase之前需要先部署好HDFS。读者也需要明确两者的联系和区别——HBase是建立在分布式文件系统HDFS上的分布式数据库系统。

1.启动HBase

启动HBase服务是使用HBase shell的前提,而因为HBase是基于HDFS的,所以得先启动HDFS的相关组件,我们先执行指令start-all.sh来启动HDFS和YARN,并使用jps查看java进程,此时应该看到NameNode和DataNode等HDFS的守护进程:

[root@zsxhost01 ~]# jps
12282 ResourceManager
12795 Jps
11773 DataNode
12445 NodeManager
12014 SecondaryNameNode
11631 NameNode
提示:因为本文是在伪分布式集群的模式下完成的,所以在启动HDFS后能在Client节点看到所有HDFS角色的守护进程,若是完全分布式集群模式下,则应该将NameNode和DataNode分别部署到不同的节点上。

再执行start-hbsae.sh来启动HBase,并使用jps查看java进程:。

14083 HQuorumPeer
14420 HRegionServer
14757 Jps
14202 HMaster
12282 ResourceManager
11773 DataNode
12445 NodeManager
12014 SecondaryNameNode
11631 NameNode
提示:因为本文是在伪分布式集群的模式下完成的,所以在启动HBase后能在Client节点看到所有HBase角色的守护进程,若是完全分布式集群模式下,则应该将HMaster和HRegionSever分别部署到不同的节点上。

可以发现在启动HBase后,多出了HMaster、HRegionSever、HQuorumPeer三个守护进程,此时说明HBase启动成功了。

2.启用HBase Shell

在启动HBase后,执行如下代码,即可启动HBase Shell。

cd $HBASE_HOME
./bin/hbase shell
#如果已经将$HBASE_HOME/bin添加进了$PATH,可以直接使用hbase shell

代码执行结果:

[root@zsxhost01 ~]# hbase shell
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/usr/local/bigdata/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/usr/local/bigdata/hbase/lib/client-facing-thirdparty/slf4j-log4j12-1.7.30.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
2021-02-24 15:40:37,789 WARN  [main] util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
HBase Shell
Use "help" to get list of supported commands.
Use "exit" to quit this interactive shell.
For Reference, please visit: http://hbase.apache.org/2.0/book.html#shell
Version 2.4.1, rb4d9639f66fccdb45fea0244202ffbd755341260, Fri Jan 15 10:58:57 PST 2021
Took 0.0013 seconds                                                                                                                                                                                               
hbase:001:0> 

观察上述代码运行结果的第一行与最后一行,可以发现我们与机器交互的解释器提示符由[root@zsxhost01 ~]变成了hbase:001:0>,后者便是HBase Shell的提示符。

3.键入HBase Shell命令操作HBase

在进入HBase交互界面以后,即可通过输入HBase Shell命令来操作HBase,这里以3条简单的命令statusversionlist为例:


hbase:001:0> status:

hbase:001:0> status
1 active master, 0 backup masters, 1 servers, 0 dead, 2.0000 average load
Took 1.3073 seconds

上述片段中:

第一行是键入的命令status;
第二行是返回的结果,意为有一个活跃的主节点,零个备用主节点,一个从节点,有零个从节点挂掉;
第三行是本条命令执行时花费的时间。


hbase:002:0> version

hbase:002:0> version
2.4.1, rb4d9639f66fccdb45fea0244202ffbd755341260, Fri Jan 15 10:58:57 PST 2021
Took 0.0003 seconds

上述片段中:

第一行是键入的命令version;
第二行是返回的结果,意为当前HBase版本是2.4.1,于 Fri Jan 15 10:58:57 PST 2021发布
第三行是本条命令执行时花费的时间。


hbase:003:0> list

hbase:003:0> list
TABLE
0 row(s)
Took 0.0414 seconds
=> []

上述片段中:

第一行是键入的命令list;
第四行是本条命令执行时花费的时间;
其余部分是返回的结果,意为当前HBase中共0张表,为空。


由以上三个命令的例子,我们不难看出,执行HBase Shell命令的返回的信息包含了执行的结果,和花费的时间。使用起HBase Shell来非常简单、清晰和方便。所以接下来我们将对一些常用的HBase Shell命令来进行了解和实践。

三、常用HBase Shell实例

1.常用的HBase Shell命令

HBase的常用命令如下图所示,该图选自《大数据 Hadoop3.X 分布式处理实战》一书的第103页:

cyml
不难看出这些常用的操作也只是一些简单的增删改查,类似常见的传统关系型数据库的操作,当然就HBase和RDBMS来说,二者也有很多区别,见下图(选自《大数据 Hadoop3.X 分布式处理实战》一书的第95页):

在这里插入图片描述
从上图不难看出,HBase的数据类型比较单一,只含字符串;事务操作简单,没有RDBMS一样花里胡哨的函数和连接;表结构简单,基于列存储;但是也因此更方便横向扩展,可伸缩性强,查询的效率更高,单位时间内吞吐量大,更适合大数据应用场景。且HBase在更新数据以后,依旧会保存一定期限内或一定数量内的旧版本数据,可靠性更强!

2.一个运用上述命令的综合实例:

  1. 使用create创建表
    格式:create ‘表名’,‘列族名1’,‘列族名2’,…,‘列族名i’
    实例代码:create '成绩表','姓名','学号','成绩'
    作用:创建一个名为’成绩表’,含有列族’姓名’,‘学号’,'成绩’的HBase表
    运行结果:
 hbase:002:0>  create '成绩表','姓名','学号','成绩'
Created table 成绩表
Took 3.6080 seconds                                                                                                                                                                                               
=> Hbase::Table - 成绩表

  1. 使用list查看当前HBase中有哪些表
    命令:list
    运行结果:
hbase:004:0>  list
TABLE                                                                                                                                                                                                             
成绩表                                                                                                                                                                                                               
1 row(s)
Took 0.0924 seconds                                                                                                                                                                                               
=> ["成绩表"]

  1. 使用describe查看指定表的构造
    格式:describe ‘表名’
    实例代码:describe '成绩表' #注:describe可简写为desc
    返回结果:
hbase:006:0>  describe '成绩表'    #注:describe可简写为desc
Table 成绩表 is ENABLED                                                                                                                                                                                              
成绩表                                                                                                                                                                                                               
COLUMN FAMILIES DESCRIPTION                                                                                                                                                                                       
{NAME => '姓名', BLOOMFILTER => 'ROW', IN_MEMORY => 'false', VERSIONS => '1', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', COMPRESSION => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', BLOCKCACHE
 => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}                                                                                                                                                       

{NAME => '学号', BLOOMFILTER => 'ROW', IN_MEMORY => 'false', VERSIONS => '1', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', COMPRESSION => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', BLOCKCACHE
 => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}                                                                                                                                                       

{NAME => '成绩', BLOOMFILTER => 'ROW', IN_MEMORY => 'false', VERSIONS => '1', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', COMPRESSION => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', BLOCKCACHE
 => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}   

  1. 使用put命令向表中插入数据
    格式:put ‘表名’,‘行键’,‘列名(列族:列名)’,‘值’

    ep4-1:插入一行数据,行键为’小张’,列族’学号’的列名为""(空字符串),值为178:put '成绩表','小张','学号:','178'
    运行结果:

    Took 0.2241 seconds
    

    ep4-2:将’小张’,这一行的数据的列族’成绩’添加3列:‘语文’,‘数学’,‘英语’:
    put '成绩表','小张','成绩:语文','114'
    put '成绩表','小张','成绩:数学','110'
    put '成绩表','小张','成绩:英语','99‘
    运行结果:

    Took 0.0105 seconds                                                                                                                                                                                               
    Took 0.0063 seconds                                                                                                                                                                                               
    Took 0.0097 seconds
    

  1. 使用get查看数据
  • ep5-1.:查看所有与’小张’相关的数据
    格式1:get ‘表名’,‘行键名’
    实例代码:get '成绩表','小张',{FORMATTER => 'toString'}
    运行结果:
 COLUMN                                                CELL                                                                                                                                                        
 学号:                                                  timestamp=2021-02-24T17:43:28.906, value=178                                                                                                                
 成绩:数学                                                timestamp=2021-02-24T17:45:03.630, value=110                                                                                                                
 成绩:英语                                                timestamp=2021-02-24T17:45:03.637, value=99                                                                                                                 
 成绩:语文                                                timestamp=2021-02-24T17:45:03.618, value=114                                                                                                                
1 row(s)
Took 0.1839 seconds    
  • ep5-2:.查看行键为’小张’的’成绩:数学’的值(乱码版)
    格式2:get ‘表名’,‘行键名’,‘列族:列名’
    实例代码:get '成绩表','小张','成绩:数学'
    运行结果:
COLUMN                                                CELL                                                                                                                                                        
 \xE6\x88\x90\xE7\xBB\xA9:\xE6\x95\xB0\xE5\xAD\xA6    timestamp=2021-02-24T17:45:03.630, value=110                                                                                                                
1 row(s)
Took 1.5206 seconds  

对比ep5-1和ep5-2,我们可以发现ep5-2选取数据时比ep5-1多了指定的要查询的列名,但是缺少了{FORMATTER => 'toString'},缺少语句的作用是:将HBase中以字节数组存储的数据格式转换为字符串,所以我们可以看到ep5-2中返回的COLUMN是一串乱码。

  • ep5-3:.查看行键为’小张’的’成绩:数学’的值
    格式3:get ‘表名’,‘行键名’,{COLUMN=>‘列族:列名’,其他选项=>‘对应的值’}
    实例代码:get '成绩表','小张',{FORMATTER => 'toString',COLUMN=>'成绩:数学'}
    运行结果:
COLUMN                                                CELL                                                                                                                                                        
 成绩:数学                                                timestamp=2021-02-24T17:45:03.630, value=110 

对比ep5-3和ep5-2,可以发现ep5-3在加上了{FORMATTER => 'toString'}格式控制语句后,其运行结果中的COLUMN没有乱码了。


  1. 使用scan查看表中的所有数据
    格式:scan ‘表名’
    实例代码:scan '成绩表',{FORMATTER => 'toString'}
    运行结果:
ROW                                                   COLUMN+CELL                                                                                                                                                 
 小张                                                   column=学号:, timestamp=2021-02-24T17:43:28.906, value=178                                                                                                    
 小张                                                   column=成绩:数学, timestamp=2021-02-24T17:45:03.630, value=110                                                                                                  
 小张                                                   column=成绩:英语, timestamp=2021-02-24T17:45:03.637, value=99                                                                                                   
 小张                                                   column=成绩:语文, timestamp=2021-02-24T17:45:03.618, value=114                                                                                                  
1 row(s)
Took 0.1136 seconds                                     

  1. 使用count统计记录条数
    格式:count ‘表名’
    实例代码:count '成绩表'
    运行结果:
1 row(s)
Took 0.4555 seconds                                                                                                                                                                                               
=> 1

  1. 使用exists判断表是否存在
    格式:exists ‘表名’
  • ep8-1:表存在的情况
    实例代码:exists '成绩表'
    运行结果:
Table 成绩表 does exist                                                                                                                                                                                              
Took 0.1909 seconds                                                                                                                                                                                               
=> true
  • ep8-2:表不存在的情况
    实例代码:exists 'scores'
    运行结果:
Table scores does not exist                                                                                                                                                                                       
Took 0.0152 seconds                                                                                                                                                                                               
=> false

  1. 使用alter更改表结构:此处为将成绩表的’成绩’列族的备份数改为三份
    通用流程:将表改为不可用,修改表的结构,再次激活表为可用。
    具体过程如下:
  • 9-1 将需要更改的表的状态标记为不可用:
    disable ‘成绩表’ #更改之前需要将表标记为不可用状态

  • 9-2.将成绩表中名为’成绩’的列族的数据备份数更改为3份
    alter ‘成绩表’,{NAME=>‘成绩’,VERSIONS=>3}

  • 9-3.将更改后的表的状态更改为可用
    enable ‘成绩表’

9-1和9-3皆仅仅返回执行时间,9-2的执行所返回的信息如下:

Updating all regions with the new schema...
All regions updated.
Done.
Took 1.7194 seconds                                                                                                                                                                                               
hbase:012:0>  enable '成绩表'
Took 0.7070 seconds   

  1. 使用delete命令删除记录
    格式:delete ‘表名’,‘行键名’,‘指定列名’
    实例代码:
    delete '成绩表','小张','成绩:数学'
    scan '成绩表',{FORMATTER => 'toString'} #查看删除后的表中记录
    运行结果:
hbase:014:0>  delete '成绩表','小张','成绩:数学'
Took 0.1207 seconds                                                                                                                                                                                               
hbase:015:0>  scan '成绩表',{FORMATTER => 'toString'} #查看删除后的表中记录
ROW                                                   COLUMN+CELL                                                                                                                                                 
 小张                                                   column=学号:, timestamp=2021-02-24T17:43:28.906, value=178                                                                                                    
 小张                                                   column=成绩:英语, timestamp=2021-02-24T17:45:03.637, value=99                                                                                                   
 小张                                                   column=成绩:语文, timestamp=2021-02-24T17:45:03.618, value=114                                                                                                  
1 row(s)
Took 0.0234 seconds                         

  1. 使用truncate清空表中的所有数据,而不改变表的结构
    格式:truncate ‘表名’
    实例代码:
    truncate '成绩表' #清空成绩表中的所有数据
    scan '成绩表' #查看truncate操作后的表中有无记录
    desc '成绩表' #查看表的结构有无改变
    运行结果:
hbase:001:0>  truncate '成绩表'
Truncating '成绩表' table (it may take a while):
Disabling table...
Truncating table...
Took 4.2816 seconds               
                 
hbase:002:0>  scan '成绩表'
ROW                                                   COLUMN+CELL                                                                                                                                                 
0 row(s)
Took 0.1075 seconds     
   
hbase:003:0>  desc '成绩表'
Table 成绩表 is ENABLED                                                                                                                                                                                              
成绩表                                                                                                                                                                                                               
COLUMN FAMILIES DESCRIPTION                                                                                                                                                                                       
{NAME => '姓名', BLOOMFILTER => 'ROW', IN_MEMORY => 'false', VERSIONS => '1', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', COMPRESSION => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', BLOCKCACHE
=> 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}                                                                                                                                                       

{NAME => '学号', BLOOMFILTER => 'ROW', IN_MEMORY => 'false', VERSIONS => '1', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', COMPRESSION => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', BLOCKCACHE
=> 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}                                                                                                                                                       

{NAME => '成绩', BLOOMFILTER => 'ROW', IN_MEMORY => 'false', VERSIONS => '3', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', COMPRESSION => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', BLOCKCACHE
=> 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}                                                                                                                                                       

3 row(s)
Quota is disabled
Took 0.2779 seconds             

通过上述结果不难发现使用scan查看成绩表中的数据记录数为0,但是使用desc查看成绩表的结构没有变化。


  1. 删除表(数据和结构都删除)
    流程:将表标记为不可用、删除表
    实例代码:
    disable '成绩表' #将表标记为不可用
    drop '成绩表' #删除表
    list #查看表是否删除成功
    运行结果:
hbase:005:0>  disable '成绩表'
Took 0.3549 seconds                
                                                                                                                                                                               
hbase:006:0>  drop '成绩表'
Took 0.1883 seconds                  
                                                                                                                                                                             
hbase:007:0> list
TABLE                                                                                                                                                                                                             
0 row(s)
Took 0.1345 seconds                                                                                                                                                                                               
=> []

通过上述结果不难发现使用list查看HBase中的表的数量为0,说明成绩表被成功地删除了。


总结

博客粗糙的介绍了HBase Shell是什么以及一些常用HBase Shell的用法,当然因为HBase是不同于传统关系型数据库的NoSQL数据库,要熟练地使用HBase Shell还需要读者取理解HBase的原理和一些核心概念,例如:行关键字、列关键字、时间戳、cell等。文中提到的《大数据 Hadoop3.X 分布式处理实战》是一部非常不错的教材,相关知识大家也可以参考该书第5、6章理解,感谢阅读。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐