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 | { |
列族→ | 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_info
、office_info
称为列族name
、city
、phone
、tel
、address
称为列row_key1
、row_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
时的**phone
从156****0000
修改为t4
时的156****0001
,读取时默认读取t4
时的phone
**值,通过这种方式完成了修改。
同样的,我们也不好删除数据,因此我们只需要插入一条**Type
**为Delete
的数据即可。
1.2.3 数据模型
Name Space 命名空间
类似于关系型数据库的 Database 概念,每个命名空间下有多个表。HBase 两个自带的命名空间,分别是
hbase
和default
,hbase
中存放的是 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 基本架构
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 分布式部署
至少 3 台虚拟机
1
2
3hadoop101
hadoop102
hadoop103保证 ZooKeeper 正常部署,并且启动 ZooKeeper
1
zkServer.sh start
保证 Hadoop 正常部署,并且启动 Hadoop
1
start-dfs.sh
配置 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 = falsehbase-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
<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
3hadoop101
hadoop102
hadoop103
⑥ 解决
log4j
不兼容的问题,移除HBase
或者Hadoop
的.jar
包⑦ 使用
scp
命令同步 HBase 配置,需要提前设置好免密登录。或者使用xsync
启动 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 高可用服务
如果 HBase 已经启动,先关闭HBase
1
stop-hbase.sh
添加配置文件
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
使用
scp
命令分发配置文件启动HBase,正常启动进程如下:
1
2
3hadoop101 -> HMaster HRegionServer
hadoop102 -> HMaster HRegionServer
hadoop103 -> HRegionServer其中,
hadoop101
的HMaster
先启动作为主节点,hadoop102
的HMaster
后启动,作为**备用节点(Backup-Master)**。
2.2 使用操作
2.2.1 Shell操作
使用命令 hbase shell
启动 HBase 的 Shell
命令界面,所有命令均可以使用 help
查到。
当我们在 hbase shell
中输入help
命令时,将会弹出HBase的使用提示:
1 | hbase shell |
1 | hbase(main):001:0> help |
根据上述信息,我们可以进一步的操作 HBase 数据库。我们实际开发中常用的**命令组(COMMAND GROUPS)**有:general
、namespace
、ddl
、dml
等,下面依次介绍这些内容:
通用命令
general
查看 HBase 状态
status
,提供 HBase 的状态,如服务器的数量等1
2
3hbase(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
3hbase(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
4hbase(main):003:0> whoami
nilera (auth:SIMPLE)
groups: nilera
Took 0.0283 seconds
操作命名空间
Namespace
**命名空间(Namespace)**,相当于MySQL数据库中的DataBase。
Namespace
命令包括:alter namespace
、create_namespace
、describe_namespace
、drop_namespace
、list_namespace
、list_namespace_tables
。下面将对一些常用命令进行介绍:查看全部命名空间
list_namespace
1
2
3
4
5
6hbase(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
9hbase(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
5hbase(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
7hbase(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
相关命令如下: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
。下面将对一些常用命令进行介绍:创建表
create
常见用法:
①
create 'ns:tb', {NAME => 'cf', VERSIONS => 5}
在命名空间
ns
下,创建一张表tb
,定义一个列族cf
。② 当在默认命名空间
default
下创建表时,可以省略ns
③
create 'tb', 'cf1', 'cf2'
在默认命名空间
default
下,创建一张表tb
,并定义两个列族cf1
、cf2
④
create 'tb', {NAME => 'cf1', VERSIONS => 5}, {NAME => 'cf2', VERSIONS => 5}
在默认命名空间
default
下,创建一张表tb
,并定义两个列族cf1
、cf2
,并同时指定两个列族的版本为5
。1
2
3
4hbase(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
12hbase(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
5hbase(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
5hbase(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
17hbase(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
5hbase(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 seconds1
2
3
4
5hbase(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
9hbase(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
2hbase(main):001:0> disable 'bigdata:person'
Took 0.9384 seconds删除表
drop
用法:
drop 'ns:tb'
或drop 'tb'
,删除表时需要保证表是禁用的,否则会出现以下错误:1
2
3
4
5
6
7hbase(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
2hbase(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
。其中col
为cf:col
(即列族:列名
)的格式。 如果重复向相同行号
rk
,相同col
写数据,则会进行覆盖。1
2
3
4
5
6
7
8
9
10
11
12
13hbase(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
读取数据的方法有两个:
get
和scan
get
最大范围是一行数据,也可以进行列的过滤,读取数据的结果为多行Cell
。scan
是扫描数据,能够读取多行数据,不建议扫描过多数据,推荐使用startRow
和stopRow
来控制读取的数据,默认范围左闭右开。
①
get
命令1
2
3
4
5
6
7
8
9
10
11
12
13
14Some examples:
t.get 'r1' #查看'r1'的数据
t.get 'r1', {TIMERANGE => [ts1, ts2]}
t.get 'r1', {COLUMN => 'c1'} #过滤单列, 只显示 'c1'
t.get 'r1', {COLUMN => ['c1', 'c2', 'c3']} #过滤多列, 只显示 'c1', 'c2', 'c3'
t.get 'r1', {COLUMN => 'c1', TIMESTAMP => ts1}
t.get 'r1', {COLUMN => 'c1', TIMERANGE => [ts1, ts2], VERSIONS => 4}
t.get 'r1', {COLUMN => 'c1', TIMESTAMP => ts1, VERSIONS => 4}
t.get 'r1', {FILTER => "ValueFilter(=, 'binary:abc')"}
t.get 'r1', 'c1'
t.get 'r1', 'c1', 'c2'
t.get 'r1', ['c1', 'c2']
t.get 'r1', {CONSISTENCY => 'TIMELINE'}
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
17hbase(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
16Some examples:
scan 'hbase:meta'
scan 'hbase:meta', {COLUMNS => 'info:regioninfo'}
scan 'ns1:t1', {COLUMNS => ['c1', 'c2'], LIMIT => 10, STARTROW => 'xyz'}
scan 't1', {COLUMNS => ['c1', 'c2'], LIMIT => 10, STARTROW => 'xyz'}
scan 't1', {COLUMNS => 'c1', TIMERANGE => [1303668804000, 1303668904000]}
scan 't1', {REVERSED => true}
scan 't1', {ALL_METRICS => true}
scan 't1', {METRICS => ['RPC_RETRIES', 'ROWS_FILTERED']}
scan 't1', {ROWPREFIXFILTER => 'row2', FILTER => "
(QualifierFilter (>=, 'binary:xyz')) AND (TimestampsFilter ( 123, 456))"}
scan 't1', {FILTER =>
org.apache.hadoop.hbase.filter.ColumnPaginationFilter.new(1, 0)}
scan 't1', {CONSISTENCY => 'TIMELINE'}
scan 't1', {ISOLATION_LEVEL => 'READ_UNCOMMITTED'}
scan 't1', {MAX_RESULT_SIZE => 123456}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15hbase(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
删除数据的方式有两个:
delete
和deleteall
delete
表示删除一个版本的数据,即为1
个Cell
,不填写版本默认删除最新的一个版本。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
27hbase(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 的命令通过连接中的两个属性 Admin
和 Table
来实现。其中 Admin
主要管理 HBase 的元数据,如创建、修改表格信息,也就是 DDL
操作;Table
主要用于表格的增加、删除数据,也就是 DML
操作。
环境搭建
使用
IDEA
创建Maven
项目,并修改pom.xml
文件,添加HBase
所需要用到的依赖。
1 | <dependencies> |
单线程使用连接
下面展示了一种单线程使用连接的方式,实际开发中实际上很少这样做。
1 | package com.sdutcm; |
多线程使用连接
实际开发中,因为 HBase 的连接是重量级的,所以我们在每个客户端中一般只创建一个(类似于单例模式)。所以我们对代码进行修改,如下:
1 | package com.sdutcm; |
- 获取
Admin
1 | // 获取 Admin |
- 创建命名空间
1 | package com.sdutcm; |
结果如下:
1 | hbase(main):001:0> list_namespace |
- 多异常处理
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 分析数据
QuickPassHBase