HBase是一个分布式的列族数据库,我们可以简单的将其看成一个kv数据库,每个[列 + rowkey + 时间戳]对应了一个单元格。

下载HBase的压缩包并解压

我们有三台机器,预计它们的角色将会如下

Node Name Master RegionServer
172.19.65.196 yes no
172.19.72.108 backup yes
172.19.72.112 no yes

在官网下载HBase的压缩包并分发到三台机器上,然后解压压缩包。

设置免密登录

学习我们在HDFS的安装和使用中了解到的SSH免密登录的方法,设置196108两台机器要能够免密访问所有的机器

搭建HDFS和ZooKeeper服务

根据文章HDFS的安装和使用ZooKeeper的简单介绍中所介绍的内容,搭建HDFS和ZooKeeper服务。

修改配置文件

修改master机器(196)的./hbase-2.4.11/conf/hbase-site.xml配置文件,设置配置如下(其它配置需要删除,只保留如下配置)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<configuration>
<property>
<!-- 设置hbase的搭建方式为分布式集群模式 -->
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<!-- 设置hdfs的地址 -->
<name>hbase.rootdir</name>
<value>hdfs://172.19.65.196:9000/hbase</value>
</property>
<property>
<!-- 设置ZooKeeper的地址 -->
<name>hbase.zookeeper.quorum</name>
<value>172.19.65.196:2181,172.19.72.108:2181,172.19.72.112:2181</value>
</property>
</configuration>

修改master节点的conf/regionservers文件如下

172.19.72.108
172.19.72.112

在master节点添加文件conf/backup-masters,把master-backup主机的地址也就是172.19.72.108设置到该文件中。

修改master节点conf/hbase-env.sh文件,添加如下配置让HBase不要启动它自己的ZooKeeper(而是使用我们已经搭建好的ZooKeeper)

export HBASE_MANAGES_ZK=false

随后把conf文件夹的内容同步另外两台机器

rsync -azvP conf hbase@172.19.72.108:/home/hbase/hbase-2.4.11
rsync -azvP conf hbase@172.19.72.112:/home/hbase/hbase-2.4.11

在三台机器的/etc/hosts文件中添加如下配置(可能需要root用户权限)

172.19.65.196   lin-65-196.localdomain lin-65-196
172.19.72.108   lin-72-108.localdomain lin-72-108
172.19.72.112   lin-72-112-auto-5.localdomain lin-72-112-auto-5

启动HBase

配置文件设置完毕之后在master节点使用如下命令启动HBase

./bin/start-hbase.sh

之后在三台机器上面执行jps命令查看进程

[hbase@lin-65-196 hbase-2.4.11]$ jps
3618 HMaster                # HBase的mater进程
3027 NameNode               # HDFS的master进程
3899 Jps
3260 SecondaryNameNode      # HDFS的master备用进程
3406 QuorumPeerMain         # ZK进程

[hbase@lin-72-108 ~]$ jps
4262 HRegionServer          # HBase的数据进程
4646 Jps
4073 QuorumPeerMain         # ZK进程
4378 HMaster                # HBase的master备用进程
3982 DataNode               # HDFS的数据进程

[hbase@lin-72-112-auto-5 ~]$ jps
3096 QuorumPeerMain         # ZK进程
3480 Jps
3276 HRegionServer          # HBase的数据进程
3005 DataNode               # HDFS的数据进程

访问http://172.19.65.196:16010查看HBase的master节点信息,访问http://172.19.72.112:16030查看HBase的数据节点信息。

HBase的使用

在一台新的机器上使用同样的HBase,在conf/hbase-site.xml中设置好ZK的地址

1
2
3
4
5
6
<configuration>
<property>
<name>hbase.zookeeper.quorum</name>
<value>172.19.65.196:2181,172.19.72.108:2181,172.19.72.112:2181</value>
</property>
</configuration>

之后使用./bin/hbase shell就可以进入HBase的交互式shell,我们可以执行help查询帮助信息,执行status查看HBase的集群信息

hbase:001:0> status
1 active master, 1 backup masters, 2 servers, 0 dead, 1.0000 average load
Took 2.1464 seconds

随后我们创建表(Table)user,同时设置三个列族(Column Family)address、social_media和info

create 'user', 'address', 'social_media', 'info'
describe 'user'

随后我们写入两行(Row)数据,行键(Row Key)分别为Zhangsan和Lisi,数据中通过列族(Column Family):列标识(Column Qualifier)的方式构成了一个列的识别。而表(Table) + 行键(Row Key) + 列族(Column Family) + 列标识(Column Qualifier)唯一定位了一个单元格(Cell),这个单元格就是我们保存最终数据的地方。

put 'user', 'Zhangsan', 'address:province', 'Jiangsu'
put 'user', 'Zhangsan', 'address:city', 'Nanjing'
put 'user', 'Zhangsan', 'social_media:email', 'zhangsan@gmail.com'
put 'user', 'Zhangsan', 'social_media:facebook', 'zhangsan123'
put 'user', 'Zhangsan', 'info:birthday', '1998-06-20'
put 'user', 'Zhangsan', 'info:degree', 'bachelor'

put 'user', 'Lisi', 'address:province', 'Zhejiang'
put 'user', 'Lisi', 'address:city', 'Hangzhou'
put 'user', 'Lisi', 'social_media:email', 'lisi@163.com'
put 'user', 'Lisi', 'social_media:facebook', 'lisi666'
put 'user', 'Lisi', 'info:birthday', '1999-02-15'
put 'user', 'Lisi', 'info:degree', 'master'

一个单元格中的数据又可以通过时间戳(Timestap)来区分为多个版本,读数据时不指定时间戳就会默认读取最新的cell数据,写数据时不指定时间戳就会使用当前时间进行写入,每一个列族都可以独立设置自己的版本数量,默认为3个。

接下来可以使用命令scan 'user'查询所有保存的数据,也可以使用get命令查询单条数据

hbase:001:0> get 'user', 'Lisi'
COLUMN                                 CELL
address:city                          timestamp=2021-04-18T14:48:51.680, value=Hangzhou
address:province                      timestamp=2021-04-18T14:48:38.708, value=Zhejiang
info:birthday                         timestamp=2021-04-18T14:49:51.524, value=1999-02-15
info:degree                           timestamp=2021-04-18T14:50:09.692, value=master
social_media:email                    timestamp=2021-04-18T14:49:15.290, value=lisi@163.com
social_media:facebook                 timestamp=2021-04-18T14:49:28.690, value=lisi666
1 row(s)
Took 0.0750 seconds

一些优化技巧

  • HBase的数据是按照RowKey的字典顺序存储的,所以为了防止大量的数据被存储在少量的RegionServer中,可以给RowKey加上不同的前缀字符串来进行特定排序;也可以对行键进行Hash算法来保证其值分布的均匀。
  • 尽量缩短列族和列标识的长度,缩短行键的长度,使用字节模式替代字符串模式保存数据。
  • region最大的阈值取值建议在8GB到50GB之间,不宜过小或过大。
  • 单个cell不超过10MB,如果超过10MB,请使用mob,若再大可以直接存在HDFS中,在HBase内存储HDFS地址。
  • 列簇数量不建议过多,一般1个即可,不建议超过3个。
  • 对于时序场景,建议rowkey设计为设备ID加上时间,如果采用“时间+设备ID”的方案会导致如下:
    • 同一时间点的数据落入同一个region,导致热点。
    • 较早数据随着时间推移、数据过期会留下大量的空地域,带来不必要的开销。

参考

搭建分布式的HBase集群
HBase使用已经存在的ZooKeeper
HBase数据模型和读写原理