HBaseExamReview

HBase 考察知识点复习

知识点(选择)

  1. Region的分裂

    HBase中,Region 是数据管理的基本单位,类似于关系型数据库中的分区。它是 HBase 数据存储和组织的核心概念之一。
    Region 的概念和特点:
    RegionHBase 数据管理的基本单位,它负责存储一定范围内的数据。每个 Region 由一个起始 RowKey 和 终止 RowKey 定义,负责存储该范围内的数据。与关系型数据库中的分区类似,HBase 中的 Region 可以根据数据量的大小进行动态调整。当一个Region 的数据量过大时,它会被 分裂 成两个新的 Region。相反,当数据量较小时,两个或多个 Region 可能会合并成一个新的Region

    MemStore 的数据超过阈值时,将数据溢写磁盘,生成一个 StoreFile 文件。当 Region 中最大Store 的大小超过阈值时,Region 分裂,等分成两个 Region,实现数据访问的负载均衡。新的 Region 的位置由 HMaster 来确定在哪个RegionServer 中。

  2. 查看表结构的命令

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
32
33
34
[subowen@bigdata ~]$ hbase shell
2024-07-05 23:04:35,655 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.1.8, rd8333e556c8ed739cf39dab58ddc6b43a50c0965, Tue Nov 19 15:29:04 UTC 2019
Took 0.0028 seconds
hbase(main):001:0> list
TABLE
logs
logs_20240606
logs_20240607
user
sdutcm:bigdata
5 row(s)
Took 1.2756 seconds
=> ["logs", "logs_20240606", "logs_20240607", "user", "sdutcm:bigdata"]

hbase(main):002:0> describe 'sdutcm:bigdata'
Table sdutcm:bigdata is ENABLED
sdutcm:bigdata
COLUMN FAMILIES DESCRIPTION
{NAME => 'info', VERSIONS => '5', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'false', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}
{NAME => 'msg', VERSIONS => '5', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'false', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}
2 row(s)
Took 0.3826 seconds

hbase(main):003:0> scan 'sdutcm:bigdata'
ROW COLUMN+CELL
2001 column=info:name, timestamp=1719026353219, value=wang
1 row(s)
Took 0.2295 seconds
hbase(main):004:0>
  1. 启动和关闭 HBase Shell 的命令

    启动 HBase Shell 之前需要保证 ZooKeeperHadoop HDFSHBase 已经启动。可以使用 hbase shell 进入 HBase Shell,在 HBase Shell 中可以使用 exitquit 退出。

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
[subowen@bigdata ~]$ zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /home/subowen/apps/zookeeper-3.4.12/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

[subowen@bigdata ~]$ zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /home/subowen/apps/zookeeper-3.4.12/bin/../conf/zoo.cfg
Mode: standalone

[subowen@bigdata ~]$ start-dfs.sh
Starting namenodes on [bigdata]
bigdata: starting namenode, logging to /home/subowen/apps/hadoop-2.7.6/logs/hadoop-subowen-namenode-bigdata.out
bigdata: starting datanode, logging to /home/subowen/apps/hadoop-2.7.6/logs/hadoop-subowen-datanode-bigdata.out
Starting secondary namenodes [0.0.0.0]
0.0.0.0: starting secondarynamenode, logging to /home/subowen/apps/hadoop-2.7.6/logs/hadoop-subowen-secondarynamenode-bigdata.out

[subowen@bigdata ~]$ start-hbase.sh
running master, logging to /home/subowen/apps/hbase-2.1.8/logs/hbase-subowen-master-bigdata.out
bigdata: running regionserver, logging to /home/subowen/apps/hbase-2.1.8/logs/hbase-subowen-regionserver-bigdata.out

[subowen@bigdata ~]$ jps
1746 NameNode
1572 QuorumPeerMain
2071 SecondaryNameNode
2874 Jps
2379 HRegionServer
1852 DataNode
2285 HMaster

[subowen@bigdata ~]$ hbase shell
2024-07-05 22:47:57,331 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.1.8, rd8333e556c8ed739cf39dab58ddc6b43a50c0965, Tue Nov 19 15:29:04 UTC 2019
Took 0.0051 seconds
hbase(main):001:0> exit

[subowen@bigdata ~]$ hbase shell
2024-07-05 22:52:46,337 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.1.8, rd8333e556c8ed739cf39dab58ddc6b43a50c0965, Tue Nov 19 15:29:04 UTC 2019
Took 0.0025 seconds
hbase(main):001:0> quit
[subowen@bigdata ~]$
  1. 启动ZooKeeper和查看 ZooKeeper 的运行状态的命令
1
2
3
4
5
6
7
8
9
[subowen@bigdata ~]$ zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /home/subowen/apps/zookeeper-3.4.12/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

[subowen@bigdata ~]$ zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /home/subowen/apps/zookeeper-3.4.12/bin/../conf/zoo.cfg
Mode: standalone
  1. 修改表结构的命令

    使用 alter 命令可以对表的结构进行修改:

    表名创建时写的所有和列族相关的信息,都可以后续通过alter修改,包括增加删除列族。

    ① 增加列族和修改信息都使用覆盖的方法

    ​ 修改列族的版本,VERSIONS => 6

    1
    2
    3
    4
    5
    hbase(main):001:0> alter 'bigdata:person', NAME => 'name', VERSIONS => 6
    Updating all regions with the new schema...
    1/1 regions updated.
    Done.
    Took 4.0145 seconds

    ​ 添加列族 tel

    1
    2
    3
    4
    5
    hbase(main):002:0> alter 'bigdata:person', NAME => 'tel', VERSIONS => 6
    Updating all regions with the new schema...
    1/1 regions updated.
    Done.
    Took 2.4498 seconds

    ​ 查看修改后的数据:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    hbase(main):003:0> describe 'bigdata:person'
    Table bigdata:person is ENABLED
    bigdata:person
    COLUMN FAMILIES DESCRIPTION
    {NAME => 'msg', VERSIONS => '6', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'fal
    se', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN
    _MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}

    {NAME => 'name', VERSIONS => '5', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'fa
    lse', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', I
    N_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}

    {NAME => 'tel', VERSIONS => '6', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'fal
    se', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN
    _MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}
    3 row(s)
    Took 0.0795 seconds

    ② 删除列族

    ​ 删除列族可以用以下两种方式:

    1
    2
    3
    4
    5
    hbase(main):001:0> alter 'bigdata:person', NAME => 'tel', METHOD => 'delete'
    Updating all regions with the new schema...
    1/1 regions updated.
    Done.
    Took 2.1046 seconds
    1
    2
    3
    4
    5
    hbase(main):002:0> alter 'bigdata:person', 'delete' => 'msg'
    Updating all regions with the new schema...
    1/1 regions updated.
    Done.
    Took 2.9721 seconds
  2. HBaseJava API中,数据表描述的对象是什么?TableDescriptor

    1
    TableDescriptor
  3. ZooKeeper 的访问端口号,HBase 的Web访问端口号

    ZooKeeper 的访问端口号为 2181

    HBase 的 Web 访问端口号为 16010

  4. 修改表中列族的Version版本的命令

1
alter 'table_name', {NAME => 'column_family', VERSIONS => number_of_versions}
  1. 删除表中数据的命令

    1
    delete 'ns:tb', 'rk', 'cf:col'
  2. 启动和关闭ZooKeeper的命令

    1
    2
    3
    4
    5
    # 启动 ZooKeeper
    zkServer.sh start

    # 关闭 ZooKeeper
    zkServer.sh stop
  3. 更新表数据的命令

    1
    alter 'ns:tb', {NAME => 'cf:col', VERSIONS => 5}
  4. HBase安装时,配置文件有那几个?

    • hbase-env.sh
    • hbase-site.xml
    • regionservers
    • .bashrc
  5. 关于NoSQL数据库有哪些?

    • HBase
    • Cassandra
    • BigTable
  6. 删除表操作

1
2
disable 'ns:tb'
drop 'ns:tb'
  1. HBase进程名,ZooKeeper 的进程名等相关进程

    • HMaster
    • HRegionServer
    • QuorumPeerMain
  2. HBase 依托于哪个文件存储系统?

    HBase 主要依托于 Hadoop HDFS

  3. 创建表的语法结构

    1
    create 'ns:tb', {NAME => 'cf', VERSIONS=5}
  4. 查询表数据的Shell语法

    1
    2
    3
    get 'r1', {COLUMN => 'cf:col'}

    scan 'ns:tb'
  5. 什么是列族COLUMN FAMILY

  6. HBase的数据类型

    • 数据类型
      • 基本数据类型
        • 字符串(String):用于存储文本数据,如名称、描述等。
        • 整数(Int):用于存储整数数据,如计数、编号等。
        • 浮点数(Float):用于存储小数数据,如金额、比率等。
        • 布尔值(Boolean):用于存储逻辑值,如是否、有效等。
      • 复合数据类型
        • 列族(Column Family):列族是HBase表中数据的组织方式,用于存储一组相关的列。列族是HBase表中数据的基本组织单位,每个列族对应一个数据节点。
        • 列(Column):列是HBase表中数据的基本单位,用于存储一组相关的单元格。列可以包含多个单元格,每个单元格对应一个数据值。
        • 单元格(Cell):单元格是HBase表中数据的基本单位,用于存储一组相关的数据值。单元格包含一个键(Row Key)、一个列(Column)和一个值(Value)。
    • 数据模型
      • NameSpace:命名空间,类似于关系型数据库的 Database 概念,每个命名空间下有多个表。HBase 两个自带的命名空间,分别是 hbasedefaulthbase 中存放的是 HBase 内置的表,default表是用户默认使用的命名空间。
      • Table:类似于关系型数据库的表概念。不同的是,HBase 定义表时只需要声明列族即可,不需要声明具体的列。因为数据存储是稀疏的,所以往 HBase 写入数据时,字段可以动态、按需指定。因此,和关系型数据库相比,HBase 能够轻松应对字段变更的场景。
      • Row:HBase 表中的每行数据都由一个 RowKey 和多个 Column(列)组成,数据是按照 RowKey 的字典顺序存储的,并且查询数据时只能根据 RowKey 进行检索,所以 RowKey 的设计十分重要。
      • Column:HBase 中的每个列都由 Column Family(列族)和 Column Qualifier(列限定符)进行限定,例如 info:nameinfo:age。建表时,只需指明列族,而列限定符无需预先定义。
      • Time Stamp:用于标识数据的不同版本Version,每条数据写入时,系统会自动为其加上该字段,其值为写入 HBase 的时间。
      • Cell:由 {rowkey, column Family:Column Qualifier, timestamp} 唯一确定的单元。Cell 中的数据全部是字节码形式存贮。

判断题

  1. HBase 本身是用 C++ 语言编写的,因此具有很高的执行效率。( × )

    HBase 本身是由 Java 语言编写的,尽管使用 Java,其执行效率还是较高的。

  2. HBase 优化目前主要工作集中于 Rowkey 优化。( × )

    HBase 的优化目前主要工作集中在 RowKey 的设计、参数优化、JVM调优等方面。

  3. 可以想象 HBase 是通过**”三维”**的表来存储数据的,通过时间戳保存数据的历史版本。( √ )

  4. 安装 HBase 完全分布式时,需要确保 SSHJDK 是可以正常使用的。( √ )

    在安装 HBase 的完全分布式部署时,确保 SSHJDK 可以正常使用是非常重要的。具体来说:

    • SSH:在分布式部署中,HBase 的各个节点之间需要进行通信和协作,而 SSH 是用于在不同节点之间建立安全连接的工具。确保节点之间可以互相访问、通信和传输文件是部署 HBase 所必需的。通常需要设置免密登录,以便在节点之间进行信息交换而无需手动输入密码。

    • JDK:HBase 是基于 Java 编程语言开发的,因此必须确保在每个节点上安装并配置了适当的 JDKHBase 运行需要 Java 环境,且为了确保 HBase 能够正常工作,必须保证每个节点都能够使用正确的 JDK 版本。

  5. Hadoop 中引入 HBase 的其中一个原因是:HDFS 在处理连续数据时比较吃力。( × )·

    HDFS 的设计目标之一就是为了有效地处理大规模数据,包括连续数据(如大文件、数据流等)和离散数据(如小文件、批量数据等)。Hadoop 中之所以引入 HBase,是需要 HBase 提供实时访问数据的能力,使得 Hadoop 生态系统更全面(此外还有高可伸缩性、高容错、多版本策略等)。

  6. 利用 HBase 技术可在廉价 PC Server 上搭建起大规模结构化存储集群。( √ )

  7. HBaseHadoop 生态系统的一个组成部分。( √ )

    HBase 是继 Google Bigtable 之后创建的分布式、开源、版本化、非关系型数据库。它是 Hadoop 生态系统的重要组件,利用 HDFS 的容错功能,提供对数据的实时读写访问。 HBase 尽管是数据库,但也可以称为数据存储系统,因为它不提供触发器、查询语言和二级索引等 RDBMS 功能。

  8. 使用 HBase 时,无需启动服务就可以直接在开发环境中调用 HBase 的相关功能。( × )

    HBase 是基于 Hadoop 的,在使用 HBase 之前需要启动 ZooKeeperHadoop 才能使用 HBase

  9. 配置 HBase 分布式部署的过程中,可以通过 cp 命令把文件复制到运行在不同机器上的节点中。( × )

    可以使用 scp 命令、rsync命令,或者基于 rsync 编写工具 xsync 进行传输。

填空题

  1. 判断表是否存在,禁用表,删除表,创建表,查看命名空间等 Shell 命令。

    • 判断表是否存在 :exists 'namespace_name:table_name'
    • 禁用/启用表:disable 'namespace_name:table_name' / enable namespace_name:table_name
    • 删除表:删除表之前需要禁用表,disable 'namespace_name:table_name',然后再删除表,drop 'namespace_name:tablename'
    • 创建表:create 'namespace_name:table_name', {NAME => 'cf1', VERSION=5}, {NAME => 'cf2', VERSION=5}
    • 查看命名空间:list_namespace
  2. HBase 的进程有哪些:关于这些进程的详细说明见 QuickPassHBase简答题 T4

    • HBase 的主要进程:HMasterHRegionServer
    • HBase 所依赖的两个外部的服务:ZooKeeperHDFS
  3. 行键是什么:rowkey

    HBase 中,行键唯一标识了 HBase 表的一行,可以通过单个行键或行键区间的方式访问表。行键保存为 字节数组 ,以字典序 排序存储。

  4. HBase 是一个什么样的分布式存储系统。(非关系型)

    Apache HBase™ 是以 HDFS 为数据存储的,一种分布式可扩展NoSQL 数据库。HBase 是一款面向列存储,用于存储处理海量数据的 NoSQL 数据库。

    HBase 的理论原型是 GoogleBigTable 论文。他是一个高可靠性高性能面向列可伸缩分布式存储系统。

简答题

  1. HBase 的基础核心组件有哪些?分别什么作用?

    • HBase-Client
      客户端,用来访问 HBase 集群。可以和 Hbase 交互,也可以和 HRegionServer 交互。通过 HBase RPC 来访问对应的接口。

      这里的客户端模式有多种,可以是 ThriftAvroRest 等。

      另外,hbase-client 自身会缓存 region 的一些信息。

    • ZooKeeper
      作用:

      • HMaster 的高可用
      • 存储 ROOT 表的地址、HMaster 的地址
      • 存储所有 HRegionServer 的状态,监控 HRegionServer 的上下限
      • 存储 HBase 的一些 SchemaTable 的元数据
    • HMaster

      HMaster可以启动多个,通过选举机制来保证只有一个 HMaster 正常运行并提供服务,其他的 HMaster 作为 standby 来保证高可用。HMaster 主要负责 Region 的管理工作。如:

      • 用户对表的增删改查
      • 管理 RegionServer 的负载均衡,调整 Region 的分布
      • RegionServer 宕机或下线后,负责迁移 RegionServer 上的 Region 到其他的 RegionServer
      • Region 在分裂后,负责分配新的 Region
    • HRegionServer
      HRegionServerHBase 中真正的工作节点,主要负责响应用户的 I/O 请求,向 HDFS 文件系统读写数据,以及 Region 的数据文件的合并和拆分等,是 HBase 中最核心的模块。

      HBase 中,一张表由多个的 HRegion 组成,一个 HRegionServer 中管理着多个 HRegion 对象。而一个 HRegion 由多个HStore 组成,每个HStore对象都对应着表的一个列族 (Column Family)。之后,一个HStore又由一个MemStore和多个StoreFile组成。这些 StoreFile 就是hbase 存储在 HDFS上的数据文件,MemStore 表示还在内存中未刷新到文件上的那些数据。

  2. HBase 的写流程, 读流程?

    • 写流程

      写流程顺序正如 API 编写顺序,首先创建 HBase 的重量级连接。

      ① 首先访问 ZooKeeper,获取 hbase:meta 表位于哪个 Region Server

      ② 访问对应的 Region Server,获取 hbase:meta 表,将其缓存到连接中,作为连接属性 MetaCache,由于 meta 表具有一定的数据量,导致了创建连接比较慢;

      之后使用创建的连接获取 Table,这是一个轻量级的连接,只有在第一次创建的时候会检查表格是否存在访问RegionServer,之后在获取 Table 时不会访问 RegionServer

      ③ 调用 Tableput 方法写入数据,此时还需要解析 RowKey,对照缓存的 MetaCache,查看具体写入的位置有哪个 RegionServer

      ④ 将数据顺序写入(追加)到 WAL,此处写入是直接落盘的,并设置专门的线程控制 WAL 预写日志的滚动(类似 Flume);

      ⑤ 根据写入命令的 RowKeyColumnFamily 查看具体写入到哪个 MemStore,并且在 MemStore 中排序

      ⑥ 向客户端发送 ACK

      ⑦ 等达到 MemStore 的刷写时机后,将数据刷写到对应的 Store 中。

    • 读流程

      读流程创建连接的方式同写流程。创建完连接后:

      ① 创建 Table 对象发送 get 请求。

      ② 优先访问 Block Cache(读缓存),查找是否之前读取过,并且可以读取 HFile 的索引信息和布隆过滤器。

      ③ 不管读缓存中是否已经有数据了(可能已经过期了),都需要再次读取写缓存和 store 中的文件。

      ④ 最终将所有读取到的数据合并版本,按照 get 的要求返回即可。

  3. HBase 的特点有哪些?优点或缺点?

    HBase的特点:(强 / 自动 / 高 / 海集 / 并 / 列 / 多 / 块 / 运行 / 稀)

    • 强一致性的读/写HBase不是”最终一致性”数据库,它非常适合于诸如高速计数器聚合等任务。

    • 自动分片HBase 中的表通过 Region 分布在集群上,而且 Region 会随着数据的增长自动拆分和重新分布。

    • 高可靠性:自动 RegionServer 故障转移,WAL 机制保证了数据写入时不会因集群异常而导致写入数据丢失,Replication 机制保证了在集群出现严重的问题时,数据不会发生丢失或损坏。而且 HBase 底层使用 HDFSHDFS 本身也有备份。

    • Hadoop/HDFS 集成&海量存储:,HBase支持 HDFS开箱即用作为其分布式文件系统。HBase 作为一个开源的分布式 Key-Value 数据库,其主要作用是面向 PB 级别数据的实时入库和快速随机访问。这主要源于上述易扩展的特点,使得 HBase 通过扩展来存储海量的数据。

    • 并行处理HBase 通过 MapReduce 支持大规模并行处理,将 HBase 用作源和接收器。

    • 列式存储HBase 是根据列族来存储数据的。列族下面可以有非常多的列。列式存储的最大好处就是,其数据在表中是按照某列存储的,这样在查询只需要少数几个字段时,能大大减少读取的数据量。(面向列)

    • 多种语言的 APIHBase 支持使用 JavaAPI 来编程进行数据的存取,还支持使用 Thrift 语言和 REST 语言的 API 来编程进行数据的存取。

    • 块缓存和布隆过滤器HBase支持 Block CacheBloom过滤器进行大容量查询优化。

    • 运行管理HBase 为业务洞察和 JMX 度量提供内置网页。

    • 稀疏性:为空的列可以不占存储空间,表可以设计的非常稀疏。

    HBase 的优点和缺点

    • HBase的优点:(动节/海存/负载/并拓)

      • 动态增加&节省空间:在传统的关系数据库中,如果数据结构发生了变化,就需要停机维护,而且需要修改表结构,而在 HBase 中数据表内的列可以做到动态增加,并且列为空的时候不存储数据,从而节省存储空间。
      • 海量数据存储HBase 适合存储 PB 数量级的海量数据,PB 级的数据在只采用廉价 PC 来存储的情况下,也可以在几十到一百毫秒内返回数据。这与 HBase 的极易扩展息息相关,正因如此,HBase 为海量数据的存储提供了便利。
      • 负载均衡:传统的通用关系数据库无法应对在数据规模剧增时导致的系统扩展性问题和性能问题。HBase 可以做到自动切分数据,并且会随着数据的增长自动地拆分和重新分布。
      • 高并发HBase 可以提供高并发的读写操作,而且可以利用廉价的计算机来处理超过 10 亿行的表数据
      • 高拓展性HBase 具有可伸缩性,如果当前集群的处理能力明显下降,可以增加集群的服务器数量来维持甚至提高处理能力。
    • HBase 的缺点:(条查/复杂/JOIN/ACID/SQL)

      • 不支持条件查询:不能支持条件查询,只支持按照 RowKey(行键)来查询,也就是只能按照主键来查询。这样在设计 RowKey 时,就需要完美的方案以设计出符合业务的查询。
      • 架构设计复杂:架构设计复杂,且使用 HDFS 作为分布式存储,因此只是存储少量数据,它也不会很快。在大数据量时,它慢的不会很明显。
      • 不支持 Join 操作HBase 不支持表的关联操作,因此数据分析是 HBase 的弱项。常见的 group byorder by 只能通过编写 MapReduce 来实现。
      • 不支持ACIDHBase部分支持了 ACID
      • 不支持SQL语句查询:查询 HBase 时不支持通过 SQL 语句进行查询。
  4. MasterRegionServer 的作用是什么?

    HBase 包含一个 Master 和许多个 RegionServer

    • Master:实现类为 HMaster,负责监控集群中所有的 RegionServer 实例。主要作用如下:

      • 管理元数据表格 hbase:meta,接收用户对表格创建修改删除的命令并执行

      • 监控 Region 是否需要进行负载均衡,故障转移和 Region 的拆分。

    • RegionServer:实现类为 HRegionServer,主要作用如下:

      • 负责数据 Cell 的处理,例如写入数据 put,查询数据 get 等。

      • 拆分合并 Region 的实际执行者,有 master 监控,有 RegionServer 执行。

编程题

Shell

  1. 创建命名空间的 Shell

    1
    create_namespace 'namespace_name'
  2. 创建表的 Shell

    1
    create 'namespace_name:table_name', {NAME => 'cf1', VERSION => 5} 
  3. 修改表的 Shell

    1
    alter 'namespace_name:table_name', NAME => 'cf1', METHOD => 'delete'
  4. 插入数据的 Shell

    1
    put 'ns:tb', 'rk', 'cf:col', 'value'
  5. 查询数据的 Shell

    • get 最大范围是一行数据,也可以进行列的过滤,读取的结果为多行 CellCell 的格式如下:{rowkey, column Familycolumn Qualifier, time Stamp}
    1
    get 'ns:tb', 'rk' , {COLUMN => 'cf:col'}
    • scan 用于扫描数据,能够读取多行数据,不建议扫描过多的数据,推荐使用 startRowstopRow 来控制读取的数据,默认范围左闭右开
    1
    scan 'namespace_name:table_name', {STARTROW => '1001',STOPROW => '1002'}

API

读写操作时

  1. 加载配置信息
  2. 获取 HBase 的链接对象
  3. 获取 Admin 对象
  4. 构造 TableName 对象
  5. 判断表是否存在
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
public class Test {
public static Connection connection = null;
static {
Configuration conf = new Configuration(); // 加载配置信息
conf.set("hbase.zookeeper.quorum", "bigdata");
try {
connection = ConnectionFactory.createConnection(conf);
} catch (IOException e) {
e.printStackTrace();
}
}

public static void closeConntction() throw IOException {
if (connection != null) {
connection.close();
}
}

/**
* @brief 判断表格是否存在
* @param namespace 命名空间名
* @param tableName 表名
* @return true 存在; false 不存在
*/
public static boolean isTableExists(String namespace, String tableName) throws IOException {
// 1. 获得 admin
Admin admin = HBaseConnection.connection.getAdmin();

// 2. 使用对应的方法, 判断表格是否存在
boolean result = false;
try {
result = admin.tableExists(TableName.valueOf(namespace, tableName));
} catch (IOException e) {
e.printStackTrace();
}

// 3. 关闭 admin
admin.close();

// 返回结果
return result;
}

/**
* @brief 向表格中插入数据
* @param namespace 命名空间名
* @param tableName 表名
* @param rowKey 行键
* @param columnFamily 列族名
* @param columnName 列名
* @param value 插入值
*/
public static void putCell(String namespace,
String tableName,
String rowKey,
String columnFamily,
String columnName,
String value) throws IOException {
// 1. 获取 Table
Table table = connection.getTable(TableName.valueOf(namespace, tableName));

// 2. 调用相关方法插入数据
// 2.1 创建 Put 对象
Put put = new Put(Bytes.toBytes(rowKey));

// 2.2. 给 Put 对象添加数据
put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnName), Bytes.toBytes(value));

// 2.3 将对象写入对应的方法
try {
table.put(put);
} catch (IOException e) {
e.printStackTrace();
}

// 3. 关闭 Table
table.close();
}

/**
* @brief 读取数据 读取对应一行的某一列
* @param namespace 命名空间名
* @param tableName 表名
* @param rowKey 行键
* @param columnFamily 列族名
* @param columnName 列名
*/
public static void getCells(String namespace,
String tableName,
String rowKey,
String columnFamily,
String columnName) throws IOException {
// 1. 获取 Table
Table table = connection.getTable(TableName.valueOf(namespace, tableName));

// 2. 调用相关方法插入数据
// 2.1 创建 Get 对象
Get get = new Get(Bytes.toBytes(rowKey)); // 如果此时不使用 addColumn 进行参数的添加, 此时则读取一整行的数据
// 2.2 如果想读取某一列的数据, 需要添加对应的参数
get.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnName));

// 2.3 也可以设置读取数据的版本
get.readAllVersions();

try {
// 3. 读取数据, 写入 Result 对象
Result result = table.get(get);

// 4. 处理数据
Cell[] cells = result.rawCells();

// 5. 测试方法: 直接把读取到的数据打印到控制台
// 如果是实际开发, 需要再额外写方法, 对应处理数据
for (Cell cell : cells) {
// Cell 存储数据比较底层, 需要进一步处理
String value = new String(CellUtil.cloneValue(cell));
System.out.println(value);
}
} catch (IOException e) {
e.printStackTrace();
}

// 6. 关闭 Table
table.close();
}

private static main(String[] args) throw IOException {
putCell("sdutcm", "bigdata", "2001", "info", "name", "zhangsan");
connection.close();
}
}

参考文献

Hadoop 综合揭秘——HBase的原理与应用 - 风尘浪子 - 博客园 (cnblogs.com)

HBase的组件

QuickPassHBase

快速上手HBase

[TOC]

⚙ 1. HBase简介

1.1 HBase的定义

Apache HBase 是以 HDFS 为数据存储的,一种分布式、可扩展的 NoSQL 数据库。

HBase 的设计理念依据 Google 的 BigTable 论文,论文中对于数据模型的首句介绍。

BigTable是一个稀疏的、分布式的、持久的多维排序映射(Map)。该映射由行键、列键和时间戳索引作为键(Key),映射中的每个值(Value)都是一个未解释的字节数组。

HBase 使用与 BigTable 非常相似的数据模型。用户将数据行存储在带标签的表中。数据行具有可排序的键和任意数量的列。该表存储稀疏,因此如果用户喜欢,同一表中的行可以具有疯狂变化的列。

1.2 HBase的数据模型

1.2.1 HBase 的逻辑结构
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
{
"row_key1": {
"personal_info": {
"name": "ZhangSan",
"city": "Beijing",
"phone": "156****0000"
},
"office_info": {
"tel": "010-1234567",
"address": "Shandong"
}
},
"row_key11": {
"personal_info": {
"city": "Shanghai",
"phone": "133****0000"
},
"office_info": {
"tel": "010-1234567",
}
},
"row_key2": {
...
}
}
列族→ personal_info office_info
RowKey↓ name city phone tel address
row_key1 ZhangSan Beijing 156****0000 010-1234567 Shandong
row_key11 Shanghai 131****0000 010-1234567
row_key2 ... ... ... ... ...

在上面的表格中:

  • personal_infooffice_info称为列族
  • namecityphoneteladdress称为
  • row_key1row_key11称为行键
  • 将一整张大表按照进行拆分,拆分为多个表,拆分后的每个表称为**块(Region)**,用于实现分布式结构。
  • 将一整张大表按照列族进行拆分,拆分为多个**存储(Store)**,用于在底层存储到不同的文件夹中,便于文件对应。

存储数据稀疏,数据存储多维,不同的行具有不同的列。数据存储整体有序,按照RowKey的字典序排列,RowKey为一个Byte数组。

1.2.2 HBase 的物理结构

物理存储结构即为数据映射关系,而在概念视图的空单元格,底层实际根本不存储。

在HDFS中划分好的存储Store如下:

personal_info
RowKey name city phone
row_key1 ZhangSan Beijing 156****0000
row_key11 Shanghai 131****0000
row_key2 ... ... ...

其底层一定是以映射(Map)的方式进行存储的,格式为**(Key, Value)Value一定是“ZhangSan”**这种字段。那么Key是什么呢?

为了确定Value值**”ZhangSan”,我们需要用Key对应到Value**,于是得到存储如下:

Row Key Column Family Column Qualifier Timestamp Type Value
row_key1 personal_info name t1 Put ZhangSan
row_key1 personal_info city t2 Put Beijing
row_key1 personal_info phone t3 Put 156****0000
row_key1 personal_info phone t4 Put 156****0001
row_key1 personal_info phone t5 Delete 156****0001

因为 HDFS 是无法修改数据的,而 HBase 需要修改数据,那么就需要解决这一问题,于是就有了**时间戳(Timestamp)**。不同版本(version)的数据根据 Timestamp 进行区分,读取数据默认读取最新的版本。

在上面的表格中,t4相对于t3来说就是进行了修改,将t3时的**phone156****0000修改为t4时的156****0001,读取时默认读取t4时的phone**值,通过这种方式完成了修改。

同样的,我们也不好删除数据,因此我们只需要插入一条**Type**为Delete的数据即可。

1.2.3 数据模型
  • Name Space 命名空间

    类似于关系型数据库的 Database 概念,每个命名空间下有多个表。HBase 两个自带的命名空间,分别是 hbasedefaulthbase 中存放的是 HBase 内置的表,default表是用户默认使用的命名空间。

  • Table

    类似于关系型数据库的概念。不同的是,HBase 定义表时只需要声明列族即可,不需要声明具体的列。因为数据存储时稀疏的,所有往HBase写入数据时,字段可以动态、按需指定。因此,和关系型数据库相比,HBase能够轻松应对字段变更的场景。

    需要注意的是,列族的存在是动态添加列(或称字段)的基础。

  • Row

    HBase 表中的每行数据都由*一个行键(RowKey)多个列(Column)组成,数据是按照 RowKey的字典顺序存储的,*并且查询数据时只能根据 RowKey进行检索**,所以RowKey的设计十分重要。

  • Column

    HBase 中的每个列都由列族(Column Family)列限定符(Column Qualifier)进行限定,例如info:name, info:age。建表时,只需指明列族,而列限定符无需预先定义。列限定符听起来很高端,其实就是列名的意思。

  • Time Stamp

    用于标识数据的**不同版本(Version)**,每条数据写入时,系统会自动为其加上该字段,其值为写入 HBase 的时间。

  • Cell

    {rowkey, Column Family: Column Qualifier, Timestamp} 唯一确定的单元,Cell 中的数据全部是字节码形式存储。

1.3 HBase 基本架构

HBase基本架构
  • Master

    主要进程,具体实现类为HMaster,通常部署在NameNode上。

    主要功能:负责通过 ZK 监控 RegionServer 进程状态,同时是所有元数据变化的接口,内部启动监控执行 region 的故障转移和拆分的线程。

    功能的详细描述

    • 管理元数据表格 hbase:meta:接收用户对表格创建、修改、删除的命令并执行。

    • 监控 RegionServer 是否需要进行负载均衡故障转移Region拆分。通过启动多个后台线程监控实现上述功能:

      • LoadBalancer 负载均衡器

        周期性监控 region分布在 RegionServer 上面是否均衡,由参数 hbase.balancer.period控制周期时间,默认5分钟。

      • CatalogJanitor元数据管理器

        定期检查和清理hbase:meta中的数据。

      • MasterProcWAL Master 预写日志处理器

        把Master需要执行的任务记录到预写日志WAL中,如果Master宕机,则让BackupMaster继续操作。

  • RegionServer

    主要进程,具体实现类为HRegionServer,通常部署在DataNode上。

    功能:主要负责数据 Cell 的处理,同时在执行区域的拆分和合并的时候,由 RegionServer 来实际执行。

    功能的详细描述

    • 负责数据 Cell 的处理,例如写入数据put,查询数据get等。
    • 拆分合并 region 的实际执行者,有 Master 监控,有RegionServer 执行。
  • ZooKeeper

    HBase 通过 ZooKeeper 来做 Master的高可用、记录 RegionServer 的部署信息、并且存储有 meta 表的位置信息。
    HBase 对于数据的读写操作时是直接访问 ZooKeeper 的,在 2.3 版本推出 Master Registry 模式,客户端可以直接访问 Master。使用此功能,会加大对 Master的压力,减轻对 ZooKeeper 的压力。

  • HDFS

    HDFS 为 HBase 提供最终的底层数据存储服务,同时为 HBase 提供高容错的支持。

上图中的Region由三个RegionServer随机管理,尽量均衡。表名hbase:meta是一个特例,他存储在HDFS,但是由Master管理。

🔧 2. 快速上手

2.1 安装部署

2.1.1 分布式部署
  1. 至少 3 台虚拟机

    1
    2
    3
    hadoop101
    hadoop102
    hadoop103
  2. 保证 ZooKeeper 正常部署,并且启动 ZooKeeper

    1
    zkServer.sh start
  3. 保证 Hadoop 正常部署,并且启动 Hadoop

    1
    start-dfs.sh
  4. 配置 HBase 环境

    ① 下载 HBase 安装包(压缩包),这里假设为hbase-2.4.11-bin.tar.gz

    ② 解压 HBase 安装包到一个文件夹

    1
    tar -zxvf /path/to/hbase-2.4.11-bin.tar.gz -C /path/to/module

    ③ 在用户目录下,添加用户环境变量

    1
    vim .bashrc
    1
    2
    3
    #HBase_HOME
    export HBASE_HOME = /path/to/module/hbase-2.4.11
    export PATH = $PATH:$HBASE_HOME/bin

    ④ 使环境变量生效

    1
    source .bashrc

    ⑤ 修改配置文件

    • hbase-env.sh

      1
      2
      3
      # 表示是否需要 HBase 管理维护一个自带的 ZooKeeper, 默认为 true
      # 我们需要使用本机已经配置好的 ZooKeeper, 所以修改为 False
      export HBASE_MANAGES_ZK = false
    • hbase-site.xml

      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
      32
      33
      34
      35
      36
      37
      <?xml version="1.0"?>
      <?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
      <configuration>
      <!-- ZooKeeper的地址 -->
      <property>
      <name>hbase.zookeeper.quorum</name>
      <value>hadoop101,hadoop102,hadoop103</value>
      </property>

      <!-- HBase数据在HDFS中的存放路径 -->
      <property>
      <name>hbase.rootdir</name>
      <value>hadoop101:8020/hbase</value>
      </property>

      <!-- HBase的运行模式 -->
      <!-- false为单机模式, HBase和ZooKeeper会运行在同一个JVM虚拟机中 -->
      <!-- true 为分布式模式 -->
      <property>
      <name>hbase.cluster.distributed</name>
      <value>true</value>
      </property>

      <!-- ZooKeeper快照的存储位置 -->
      <!-- 这里替换为自己的 /path/to/ZooKeeperDir -->
      <property>
      <name>hbase.zookeeper.property.dataDir</name>
      <value>/opt/module/zookeeper-3.4.6/data</value>
      </property>

      <!-- HBase 安全模式 -->
      <!-- 在分布式模式下, 设置为 false -->
      <property>
      <name>hbase.unsafe.stream.capability.enforce</name>
      <value>false</value>
      </property>
      </configuration>
    • regionservers

      1
      2
      3
      hadoop101
      hadoop102
      hadoop103

    ⑥ 解决 log4j 不兼容的问题,移除 HBase或者 Hadoop.jar

    ⑦ 使用 scp 命令同步 HBase 配置,需要提前设置好免密登录。或者使用 xsync

  5. 启动 HBase 服务

    • 单点启动

      1
      2
      3
      4
      #单点启动HMaster
      hbase-daemon.sh start master
      #单点启动HRegionServer
      hbase-daemon.sh start regionserver
    • 集群启动

      1
      start-hbase.sh
    • 停止服务

      1
      stop-hbase.sh
2.1.2 高可用服务
  1. 如果 HBase 已经启动,先关闭HBase

    1
    stop-hbase.sh
  2. 添加配置文件 backup-masters

    1
    2
    3
    #使用touch命令或者echo命令均可
    touch /path/to/hbase-2.1.4/conf/backup-masters
    vim /path/to/hbase-2.1.4/conf/backup-masters

    添加内容:hadoop102

  3. 使用 scp 命令分发配置文件

  4. 启动HBase,正常启动进程如下:

    1
    2
    3
    hadoop101 -> HMaster HRegionServer
    hadoop102 -> HMaster HRegionServer
    hadoop103 -> HRegionServer

    其中,hadoop101HMaster 先启动作为主节点,hadoop102HMaster后启动,作为**备用节点(Backup-Master)**。

2.2 使用操作

2.2.1 Shell操作

使用命令 hbase shell 启动 HBase 的 Shell 命令界面,所有命令均可以使用 help 查到。

当我们在 hbase shell中输入help命令时,将会弹出HBase的使用提示:

1
hbase shell
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
hbase(main):001:0> help
HBase Shell, version 2.1.8, rd8333e556c8ed739cf39dab58ddc6b43a50c0965, Tue Nov 19 15:29:04 UTC 2019
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, close_region, compact, compact_rs, compaction_state, flush, hbck_chore_run, is_in_maintenance_mode, list_deadservers, major_compact, merge_region, move, normalize, normalizer_enabled, normalizer_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: 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, 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

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 数据库。我们实际开发中常用的**命令组(COMMAND GROUPS)**有:generalnamespaceddldml等,下面依次介绍这些内容:

  • 通用命令 general

    • 查看 HBase 状态 status,提供 HBase 的状态,如服务器的数量等

      1
      2
      3
      hbase(main):001:0> status
      1 active master, 0 backup masters, 1 servers, 0 dead, 4.0000 average load
      Took 0.5268 seconds
    • 查看 HBase 版本 version,提供正在使用 HBase 版本

      1
      2
      3
      hbase(main):002:0> version
      2.1.8, rd8333e556c8ed739cf39dab58ddc6b43a50c0965, Tue Nov 19 15:29:04 UTC 2019
      Took 0.0002 seconds
    • 表引用命令提供帮助 table_help

    • 提供有关用户的信息 whoami

      1
      2
      3
      4
      hbase(main):003:0> whoami
      nilera (auth:SIMPLE)
      groups: nilera
      Took 0.0283 seconds
  • 操作命名空间 Namespace

    **命名空间(Namespace)**,相当于MySQL数据库中的DataBase。Namespace 命令包括:alter namespacecreate_namespacedescribe_namespacedrop_namespacelist_namespacelist_namespace_tables。下面将对一些常用命令进行介绍:

    • 查看全部命名空间 list_namespace

      1
      2
      3
      4
      5
      6
      hbase(main):001:0> list_namespace
      NAMESPACE
      default
      hbase
      2 row(s)
      Took 0.5484 seconds
    • 创建命名空间 create_namespace

      用法:create_namespace 'ns'

      1
      2
      3
      4
      5
      6
      7
      8
      9
      hbase(main):001:0> create_namespace 'bigdata'
      Took 0.0432 seconds
      hbase(main):002:0> list_namespace
      NAMESPACE
      bigdata
      default
      hbase
      3 row(s)
      Took 0.0224 seconds
    • 删除命名空间 drop_namespace

      用法:drop_namespace 'ns',删除命名空间时,命名空间必须为空。

    • 查看命名空间 describe_namespace

      用法:describe_namespace 'ns'

      1
      2
      3
      4
      5
      hbase(main):001:0> describe_namespace 'bigdata'
      DESCRIPTION
      {NAME => 'bigdata'}
      Took 0.0068 seconds
      => 1
    • 查看命名空间下的表 list_namespace_tables

      用法:list_namespace_tables 'ns'

      1
      2
      3
      4
      5
      6
      7
      hbase(main):001:0> list_namespace_tables 'default'
      TABLE
      logs
      user
      2 row(s)
      Took 0.3790 seconds
      => ["logs", "user"]
  • 数据定义语言 ddl

    DDL(Data Definition Language)数据定义语言,主要是进行定义/改变表的结构、数据类型、表之间的链接等操作。ddl 相关命令如下:alteralter_asyncalter_statusclone_table_schemacreatedescribedisabledisable_alldropdrop_allenableenable_allexistsget_tableis_disabledis_enabledlistlist_regionslocate_regionshow_filters。下面将对一些常用命令进行介绍:

    • 创建表 create

      常见用法:

      create 'ns:tb', {NAME => 'cf', VERSIONS => 5}

      ​ 在命名空间 ns 下,创建一张表 tb,定义一个列族 cf

      ② 当在默认命名空间default下创建表时,可以省略 ns

      create 'tb', 'cf1', 'cf2'

      ​ 在默认命名空间default下,创建一张表tb,并定义两个列族 cf1cf2

      create 'tb', {NAME => 'cf1', VERSIONS => 5}, {NAME => 'cf2', VERSIONS => 5}

      ​ 在默认命名空间default下,创建一张表tb,并定义两个列族 cf1cf2,并同时指定两个列族的版本为 5

      1
      2
      3
      4
      hbase(main):001:0> create 'bigdata:person', {NAME => 'name', VERSIONS => 5}, {NAME => 'msg', VERSIONS => 5}
      Created table bigdata:person
      Took 1.5638 seconds
      => Hbase::Table - bigdata:person
    • 查看表的详细信息 describe

      用法describe 'tb'

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      hbase(main):010:0> describe 'bigdata:person'
      Table bigdata:person is ENABLED
      bigdata:person
      COLUMN FAMILIES DESCRIPTION
      {NAME => 'msg', VERSIONS => '5', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'fal
      se', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN
      _MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}
      {NAME => 'name', VERSIONS => '5', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'fa
      lse', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', I
      N_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}
      2 row(s)
      Took 0.1536 seconds
    • 修改表 alter

      表名创建时写的所有和列族相关的信息,都可以后续通过alter修改,包括增加删除列族。

      ① 增加列族和修改信息都使用覆盖的方法

      ​ 修改列族的版本,VERSIONS => 6

      1
      2
      3
      4
      5
      hbase(main):001:0> alter 'bigdata:person', NAME => 'name', VERSIONS => 6
      Updating all regions with the new schema...
      1/1 regions updated.
      Done.
      Took 4.0145 seconds

      ​ 添加列族 tel

      1
      2
      3
      4
      5
      hbase(main):002:0> alter 'bigdata:person', NAME => 'tel', VERSIONS => 6
      Updating all regions with the new schema...
      1/1 regions updated.
      Done.
      Took 2.4498 seconds

      ​ 查看修改后的数据:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      hbase(main):003:0> describe 'bigdata:person'
      Table bigdata:person is ENABLED
      bigdata:person
      COLUMN FAMILIES DESCRIPTION
      {NAME => 'msg', VERSIONS => '6', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'fal
      se', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN
      _MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}

      {NAME => 'name', VERSIONS => '5', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'fa
      lse', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', I
      N_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}

      {NAME => 'tel', VERSIONS => '6', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'fal
      se', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN
      _MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}
      3 row(s)
      Took 0.0795 seconds

      ② 删除列族

      ​ 删除列族可以用以下两种方式:

      1
      2
      3
      4
      5
      hbase(main):001:0> alter 'bigdata:person', NAME => 'tel', METHOD => 'delete'
      Updating all regions with the new schema...
      1/1 regions updated.
      Done.
      Took 2.1046 seconds
      1
      2
      3
      4
      5
      hbase(main):002:0> alter 'bigdata:person', 'delete' => 'msg'
      Updating all regions with the new schema...
      1/1 regions updated.
      Done.
      Took 2.9721 seconds

      ​ 然后查询修改后的数据:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      hbase(main):003:0> describe 'bigdata:person'
      Table bigdata:person is ENABLED
      bigdata:person
      COLUMN FAMILIES DESCRIPTION
      {NAME => 'name', VERSIONS => '5', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'fa
      lse', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', I
      N_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}
      1 row(s)
      Took 0.0391 seconds
    • 禁用表 disable

      用法disable 'ns:tb'disable 'tb'

      1
      2
      hbase(main):001:0> disable 'bigdata:person'
      Took 0.9384 seconds
    • 删除表 drop

      用法drop 'ns:tb'drop 'tb',删除表时需要保证表是禁用的,否则会出现以下错误:

      1
      2
      3
      4
      5
      6
      7
      hbase(main):001:0> drop 'bigdata:person'

      ERROR: Table bigdata:person is enabled. Disable it first.

      For usage try 'help "drop"'

      Took 0.0248 seconds

      ​ 禁用表后再删除表:

      1
      2
      hbase(main):001:0> drop 'bigdata:person'
      Took 1.7106 seconds
  • 数据操纵语言 dml

    DML(Data Manipulation Language)数据操纵语言,主要是对数据进行增加、删除、修改操作。

    • 写入数据 put

      HBase 中如果想要写入数据,只能添加结构中最底层的 Cell。可以手动写入时间戳指定 Cell 的版本,推荐不写,默认使用当前的系统时间。如果重复写入相同 rowKey,相同列的数据,会写入多个版本进行覆盖。所以他同时兼具写入修改的功能。

      用法

      put 'ns:tb', 'rk', 'col', 'value'

      ​ 向命名空间ns中的tb表中的行键为rk,列为col的位置写入值value。其中colcf:col(即列族:列名)的格式。

      ​ 如果重复向相同行号rk,相同col写数据,则会进行覆盖。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      hbase(main):001:0> put 'bigdata:student', '1001', 'info:name', 'zhangsan'
      Took 0.2415 seconds
      hbase(main):002:0> put 'bigdata:student', '1001', 'info:name', 'lisi'
      Took 0.0121 seconds
      hbase(main):003:0> put 'bigdata:student', '1001', 'info:name', 'wangwu'
      Took 0.0342 seconds

      hbase(main):004:0> put 'bigdata:student', '1002', 'info:name', 'zhaoliu'
      Took 0.0082 seconds
      hbase(main):005:0> put 'bigdata:student', '1003', 'info:age', '10'
      Took 0.0050 seconds
      hbase(main):006:0> put 'bigdata:student', '1003', 'info:sex', 'male'
      Took 0.0054 seconds

      put 't1', 'r1', 'c1', 'value'用法同上。

    • 读取数据 get/scan

      读取数据的方法有两个:getscan

      • get最大范围是一行数据,也可以进行列的过滤,读取数据的结果为多行 Cell

      • scan是扫描数据,能够读取多行数据,不建议扫描过多数据,推荐使用 startRowstopRow 来控制读取的数据,默认范围左闭右开。

      get命令

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      Some examples:
      hbase> t.get 'r1' #查看'r1'的数据
      hbase> t.get 'r1', {TIMERANGE => [ts1, ts2]}
      hbase> t.get 'r1', {COLUMN => 'c1'} #过滤单列, 只显示 'c1'
      hbase> t.get 'r1', {COLUMN => ['c1', 'c2', 'c3']} #过滤多列, 只显示 'c1', 'c2', 'c3'
      hbase> t.get 'r1', {COLUMN => 'c1', TIMESTAMP => ts1}
      hbase> t.get 'r1', {COLUMN => 'c1', TIMERANGE => [ts1, ts2], VERSIONS => 4}
      hbase> t.get 'r1', {COLUMN => 'c1', TIMESTAMP => ts1, VERSIONS => 4}
      hbase> t.get 'r1', {FILTER => "ValueFilter(=, 'binary:abc')"}
      hbase> t.get 'r1', 'c1'
      hbase> t.get 'r1', 'c1', 'c2'
      hbase> t.get 'r1', ['c1', 'c2']
      hbase> t.get 'r1', {CONSISTENCY => 'TIMELINE'}
      hbase> t.get 'r1', {CONSISTENCY => 'TIMELINE', REGION_REPLICA_ID => 1}
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      hbase(main):001:0> get 'bigdata:student', '1001'
      COLUMN CELL
      info:name timestamp=1717580289267, value=wangwu
      1 row(s)
      Took 0.0645 seconds

      hbase(main):002:0> get 'bigdata:student', '1001', {COLUMN => 'info:name'}
      COLUMN CELL
      info:name timestamp=1717580289267, value=wangwu
      1 row(s)
      Took 0.0107 seconds

      hbase(main):003:0> get 'bigdata:student', '1003', {COLUMN => 'info:age'}
      COLUMN CELL
      info:age timestamp=1717580366636, value=10
      1 row(s)
      Took 0.0185 seconds

      scan 命令

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      Some examples:
      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}
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      hbase(main):001:0> scan 'bigdata:student'
      ROW COLUMN+CELL
      1001 column=info:name, timestamp=1717580289267, value=wangwu
      1002 column=info:name, timestamp=1717580320927, value=zhaoliu
      1003 column=info:age, timestamp=1717580366636, value=10
      1003 column=info:sex, timestamp=1717581149533, value=male
      3 row(s)
      Took 0.0338 seconds

      hbase(main):025:0> scan 'bigdata:student', {STARTROW => '1001', STOPROW => '1003'}
      ROW COLUMN+CELL
      1001 column=info:name, timestamp=1717580289267, value=wangwu
      1002 column=info:name, timestamp=1717580320927, value=zhaoliu
      2 row(s)
      Took 0.0118 seconds
    • 删除数据 delete/deleteall

      删除数据的方式有两个:deletedeleteall

      • delete 表示删除一个版本的数据,即为 1Cell,不填写版本默认删除最新的一个版本。
      • deleteall 表示删除所有版本的数据,即为当前行当前列的多个 Cell。执行命令会标记数据为要删除,不会直接彻底删除,删除只在特定时期清理磁盘时进行。

      delete

      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
      hbase(main):001:0> put 'bigdata:student', '1001', 'info:name', 'zhangsan'
      Took 0.3910 seconds
      hbase(main):002:0> put 'bigdata:student', '1001', 'info:name', 'lisi'
      Took 0.2024 seconds
      hbase(main):003:0> put 'bigdata:student', '1001', 'info:name', 'wangwu'
      Took 0.1559 seconds

      hbase(main):004:0> scan 'bigdata:student'
      ROW COLUMN+CELL
      1001 column=info:name, timestamp=1717584831277, value=wangwu
      1002 column=info:name, timestamp=1717580320927, value=zhaoliu
      1003 column=info:age, timestamp=1717580366636, value=10
      1003 column=info:sex, timestamp=1717581149533, value=male
      3 row(s)
      Took 0.0083 seconds

      hbase(main):005:0> delete 'bigdata:student', '1001', 'info:name'
      Took 0.0055 seconds

      hbase(main):006:0> scan 'bigdata:student'
      ROW COLUMN+CELL
      1001 column=info:name, timestamp=1717584831277, value=lisi
      1002 column=info:name, timestamp=1717580320927, value=zhaoliu
      1003 column=info:age, timestamp=1717580366636, value=10
      1003 column=info:sex, timestamp=1717581149533, value=male
      3 row(s)
      Took 0.0087 seconds

      deleteall

      1
          
2.2.2 API操作

根据官方 API 介绍,HBase 的客户端连接由 ConnectionFactory 类来创建,用户使用完成之后需要手动关闭连接。同时连接是一个重量级的,推荐一个进程使用一个连接。对 HBase 的命令通过连接中的两个属性 AdminTable 来实现。其中 Admin 主要管理 HBase 的元数据,如创建、修改表格信息,也就是 DDL 操作;Table 主要用于表格的增加、删除数据,也就是 DML 操作。

  • 环境搭建

    使用 IDEA 创建 Maven 项目,并修改 pom.xml 文件,添加 HBase 所需要用到的依赖。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<dependencies>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.4.11</version>
<!-- 如果报错, 需要排除 javax.el 拓展 -->
<!-- 因为 2.4.11 对应的是一个测试版本的 javax.el 包 -->
<!-- 需要先排除这个包后再添加正式版的 javax.el 包 -->
<exclusions>
<exclusion>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
</exclusion>
</exclusions>
</dependency>

<!-- 添加正式版的 javax.el 包 -->
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.1-b06</version>
</dependency>
</dependencies>
  • 单线程使用连接

    下面展示了一种单线程使用连接的方式,实际开发中实际上很少这样做。

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
32
33
package com.sdutcm;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.AsyncConnection;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.CompletableFuture;


public class HBaseConnection {
public static void main(String[] args) throws IOException {
// 1. 创建连接配置对象
Configuration conf = new Configuration();

// 2. 添加配置参数
conf.set("hbase.zookeeper.quorum", "bigdata"); // 这些配置都写在 hbase-site.xml 中

// 3. 创建连接
// 默认创建同步连接
Connection connection = ConnectionFactory.createConnection(conf);

// 也可以创建异步连接: 不推荐使用异步连接
CompletableFuture<AsyncConnection> asyncConnection = ConnectionFactory.createAsyncConnection(conf);

// 4. 使用连接
System.out.println(connection);

// 5. 关闭连接
connection.close();
}
}
  • 多线程使用连接

    实际开发中,因为 HBase 的连接是重量级的,所以我们在每个客户端中一般只创建一个(类似于单例模式)。所以我们对代码进行修改,如下:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.sdutcm;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.AsyncConnection;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.CompletableFuture;


public class HBaseConnection {
// 声明一个静态属性
public static Connection connection = null;

static {
// 1. 创建连接配置对象: 当完成 resources 目录的配置后, 我们可以直接注释掉创建配置的部分
// 直接进行创建连接操作
// Configuration conf = new Configuration();

// 2. 添加配置参数
// 实际开发中, 不应该在代码中显式的写参数, 而是将参数写在 resources 下的配置文件中
// 将虚拟机的 hbase-site.xml 放到 resources 目录下
// conf.set("hbase.zookeeper.quorum", "bigdata"); // 这些配置都写在 hbase-site.xml 中

// 3. 创建连接
// 默认创建同步连接
try {
// 这里修改为无参构造
// connection = ConnectionFactory.createConnection(conf);
// 这里通过查看 ConnectionFactory.createConnection() -> 查看 create() -> 可以发现 HBase 官方文档添加了两个配置文件
// 分别为 hbase-default.xml 和 hbase-site.xml
// 所以我们可以直接复制虚拟机的 hbase-site.xml 添加到 resources 目录下, 并且将这里改为无参构造
// 无参则默认使用读取本地 hbase-site.xml 文件的方式添加参数
connection = ConnectionFactory.createConnection();
} catch (IOException e) {
e.printStackTrace();
}
}

// 关闭连接方式
public static void closeConnection() throws IOException {
// 判断连接是否为空
if (connection != null) {
connection.close();
}
}

public static void main(String[] args) throws IOException {
// 直接使用创建好的连接, 不要在 main 线程里面单独创建连接
System.out.println(HBaseConnection.connection);

// 使用完连接后需要关闭连接
HBaseConnection.closeConnection();
}
}
  • 获取 Admin
1
2
3
// 获取 Admin
// Admin 的连接式轻量级的, 不是线程安全的, 不推荐池化或者缓存这个连接
Admin admin = connection.getAdmin();
  • 创建命名空间
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.sdutcm;

import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;

import java.io.IOException;

public class HBaseDDL {
// 声明一个静态属性, 这样我们可以在不同的类中, 调用到同一个对象
public static Connection connection = HBaseConnection.connection;

/**
* @brief 创建命名空间
* @param namespace 命名空间名称
*/
public static void createNamespace(String namespace) throws IOException {
// 1. 获取 Admin
// Admin 的连接式轻量级的, 不是线程安全的, 不推荐池化或者缓存这个连接
Admin admin = connection.getAdmin();

// 2. 调用方法创建命名空间
// 2.1 创建命名空间描述
NamespaceDescriptor.Builder builder = NamespaceDescriptor.create(namespace);

// 2.2 给命名空间添加需求
builder.addConfiguration("user", "sdutcm");

// 2.3 使用 builder 构造出对应的添加完参数的对象, 完成创建
admin.createNamespace(builder.build());

// 关闭 admin
admin.close();
}

public static void main(String[] args) throws IOException {
// 测试创建命名空间
createNamespace("sdutcm");

// 其他代码
System.out.println("其他代码");

// 关闭 HBase 连接
HBaseConnection.closeConnection();
}
}

​ 结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
hbase(main):001:0> list_namespace
NAMESPACE
default
hbase
sdutcm <<< 可以看到 sdutcm 已经被创建出来了
3 row(s)
Took 8.0120 seconds

hbase(main):002:0> describe_namespace "sdutcm"
DESCRIPTION
{NAME => 'sdutcm', user => 'sdutcm'} <<< 这里是我们添加的描述
Took 0.7576 seconds
=> 1
  • 多异常处理
1

  • 判断表格是否存在
  • 创建表格

📕 3. 底层原理

3.1 进程架构

3.1.1 Master架构
3.1.2 RegionServer架构

3.2 写流程

3.2.1 写入顺序
3.2.2 刷新机制

3.3 读流程

3.3.1 读取顺序
3.3.2 合并数据优化

3.4 文件合并

3.4.1 大合并
3.4.2 小合并

Region拆分

自定义预分区
系统拆分

🔧 企业开发

TSDB模式

基础表格模式

自定义API
整合框架
Phoenix 读写数据
Hive 分析数据

在 Hadoop 高可用的基础上搭建 HBase 高可用

在 Hadoop 高可用的基础上搭建 HBase 高可用

当Hadoop高可用搭建完成后,需要进一步再Hadoop高可用集群上搭建HBase高可用时,过程如下:

  1. 前提说明:

    我的集群为三台机器,每台机器上都有ZooKeeper,使用用户名和主机名(Username@Hostname)分别如下:

    1
    2
    3
    master@master
    master@slaver01
    master@slaver02
  2. 首先保证 ZooKeeper 正常部署

    1
    zkServer.sh start
  3. 需要保证Hadoop正常部署

    1
    2
    [master@master ~]$ start-dfs.sh
    [master@slaver01 ~]$ start-yarn.sh
  4. 解压HBase

  5. 配置环境变量

  6. 生效环境变量

  7. 修改配置文件

    • 修改 hbase-site.xml 文件

      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
      32
      33
      34
      35
      36
      <configuration>
      <!-- HBase数据在HDFS中的存放的路径 -->
      <!-- 这里 ns 是 Hadoop 的 nameservice的值, 指向的是一个高可用的通道 -->
      <property>
      <name>hbase.rootdir</name>
      <value>hdfs://ns/hbase</value>
      </property>

      <!-- HBase 的运行模式 -->
      <!-- false是单机模式, 若为 false, HBase 和 ZooKeeper 会运行在同一个 JVM 里面 -->
      <!-- true是分布式模式 -->
      <property>
      <name>hbase.cluster.distributed</name>
      <value>true</value>
      </property>

      <!-- ZooKeeper的地址 -->
      <property>
      <name>hbase.zookeeper.quorum</name>
      <value>master,slaver01,slaver02</value>
      </property>

      <!-- ZooKeeper快照的存储位置 -->
      <property>
      <name>hbase.zookeeper.property.dataDir</name>
      <value>/opt/module/zookeeper-3.4.6/data</value>
      </property>

      <!-- V2.1版本,在伪分布式情况下, 设置为 false -->
      <!-- 当使用 hdfs 时, 设置为 true -->
      <property>
      <name>hbase.unsafe.stream.capability.enforce</name>
      <value>false</value>
      </property>
      </configuration>

      需要注意的是:

      这里使用了ns这个高可用通道,因此需要将Hadoop的 core-site.xmlhdfs-site.xml移动到/opt/module/hbase-2.1.0/conf

    • 修改 regionserver 文件

      1
      2
      3
      master
      slaver01
      slaver02