文章目录

  • 1 HBase 简介
  • 1.1 HBase 定义
  • 1.2 HBase 数据模型
  • 1.2.1 HBase 逻辑结构
  • 1.2.2 HBase 物理存储结构
  • 1.2.3 数据模型
  • 1.3 HBase 基本架构
  • 2 HBase 快速入门
  • 2.1 HBase 安装部署
  • 2.1.1 Zookeeper 正常部署
  • 2.1.2 Hadoop 正常部署
  • 2.1.3 HBase 的解压
  • 2.1.4 HBase 的配置文件
  • 2.1.6 HBase 服务的启动
  • 2.2 HBase Shell 操作
  • 2.2.1 基本操作
  • 2.2.2 表的操作
  • 3 HBase 进阶
  • 3.1 架构原理
  • 3.2 写流程
  • 3.3 MemStore Flush
  • 3.4 读流程
  • 3.5 StoreFile Compaction
  • 3.6 Region Split


1 HBase 简介

HBase —— Hadoop Database的简称,Google BigTable的另一种开源实现方式,从问世之初,就为了解决用大量廉价的机器高速存取海量数据、实现数据分布式存储提供可靠的方案。从功能上来讲,HBase不折不扣是一个数据库,与我们熟悉的Oracle、MySQL、MSSQL等一样,对外提供数据的存储和读取服务。而从应用的角度来说,HBase与一般的数据库又有所区别,HBase本身的存取接口相当简单,不支持复杂的数据存取,更不支持SQL等结构化的查询语言;HBase也没有除了rowkey以外的索引,所有的数据分布和查询都依赖rowkey。所以,HBase在表的设计上会有很严格的要求。架构上,HBase是分布式数据库的典范,这点比较像MongoDB的sharding模式,能根据键值的大小,把数据分布到不同的存储节点上,MongoDB根据configserver来定位数据落在哪个分区上,HBase通过访问Zookeeper来获取-ROOT-表所在地址,通过-ROOT-表得到相应.META.表信息,从而获取数据存储的region位置。

1.1 HBase 定义

HBase,是一种分布式、可扩展、支持海量数据存储的 NoSQL 数据库。

1.2 HBase 数据模型

逻辑上,HBase 的数据模型同关系型数据库很类似,数据存储在一张表中,有行有列。但从 HBase 的底层物理存储结构(K-V)来看,HBase 更像是一个 multi-dimensional map。

1.2.1 HBase 逻辑结构

hbase22端口拒绝连接 hbase 16000端口_nosql

1.2.2 HBase 物理存储结构

hbase22端口拒绝连接 hbase 16000端口_大数据_02

1.2.3 数据模型
  1. Name Space
    命名空间,类似于关系型数据库的 DatabBase 概念,每个命名空间下有多个表。HBase有两个自带的命名空间,分别是 hbase 和 default ,hbase 中存放的是 HBase 内置的表,default 表是用户默认使用的命名空间。
  2. Region
    类似于关系型数据库的表概念。不同的是,HBase 定义表时只需要声明 字段可以动态、按需指定 。因此,和关系型数据库相比,HBase 能够轻松应对字段变更的场景。
  3. Row HBase 表中的每行数据都由一个 RowKey 和多个 Column(列) 组成,数据是按照 RowKey的 字典顺序存储的 ,并且查询数据时只能根据 RowKey 进行检索,所以 RowKey 的设计十分重要。
  4. Column HBase 中的每个列都由 Column Family(列族)和 Column Qualifier(列限定符)进行限定,例如 info:name,info:age。建表时,只需指明列族,而列限定符无需预先定义。
  5. Time Stamp
    用于标识数据的不同版本(version),每条数据写入时,如果不指定时间戳,系统会自动为其加上该字段,其值为写入 HBase 的时间。
  6. Cell 由 {rowkey, column Family:column Qualifier, time Stamp} 唯一确定的单元,是Hbase的 最小单元 。cell 中的数据是没有类型的,全部是字节码形式存贮。

1.3 HBase 基本架构

hbase22端口拒绝连接 hbase 16000端口_hbase_03


架构角色:

  1. Region Server
    Region Server 为 Region 的管理者,其实现类为 HRegionServer,主要作用如下:
    对于数据的操作:get, put, delete;
    对于 Region 的操作:splitRegion、compactRegion。
  2. Master
    Master 是所有 Region Server 的管理者,其实现类为 HMaster,主要作用如下:
    对于表的操作:create, delete, alter
    对于 RegionServer的操作:
    分配 regions到每个RegionServer,监控每个 RegionServer的状态,负载均衡和故障转移。
  3. Zookeeper
    HBase 通过 Zookeeper 来做 Master 的高可用、RegionServer 的监控、元数据的入口以及集群配置的维护等工作。
  4. HDFS
    HDFS 为 HBase 提供最终的底层数据存储服务,同时为 HBase 提供高可用的支持。

2 HBase 快速入门

2.1 HBase 安装部署

2.1.1 Zookeeper 正常部署

首先保证 Zookeeper 集群的正常部署,并启动之:
这里先展示hadoop104,105、106一样操作`

[zjw@hadoop104 ~]$ cd /opt/module/zk/zookeeper-3.5.7
[zjw@hadoop104 zookeeper-3.4.10]$ bin/zkServer.sh start
2.1.2 Hadoop 正常部署

Hadoop 集群的正常部署并启动:

myhadoop.sh start
2.1.3 HBase 的解压

解压 Hbase 到指定目录:

tar -zxvf hbase-1.3.1-bin.tar.gz -C /opt/module

hbase22端口拒绝连接 hbase 16000端口_hbase22端口拒绝连接_04

2.1.4 HBase 的配置文件

修改 HBase 对应的配置文件
1):hbase-env.sh 修改内容

export JAVA_HOME=/opt/module/jdk1.6.0_144
export HBASE_MANAGES_ZK=false

2)hbase-site.xml 修改内容

<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://hadoop104:9870/HBase</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
 <!-- 0.98 后的新变动,之前版本没有.port,默认端口为 60000 -->
<property>
<name>hbase.master.port</name>
<value>16000</value>
</property>
<property> 
<name>hbase.zookeeper.quorum</name>
 <value>hadoop104,hadoop105,hadoop106</value>
 </property>
<property> 
<name>hbase.zookeeper.property.dataDir</name>
 <value>/opt/module/zookeeper-3.5.7/zkData</value>
</property>
</configuration>

3)regionservers:

hadoop104
hadoop105
hadoop106

4)软连接 hadoop 配置文件到 HBase:

ln -s /opt/module/hadoop/hadoop-3.1.3/etc/hadoop/core-site.xml /opt/module/hbase-1.3.1/conf/core-site.xml
ln -s /opt/module/hadoop/hadoop-3.1.3/etc/hadoop/hdfs-site.xml /opt/module/hbase-1.3.1/conf/hdfs-site.xml

5)分发hbase文件到其它节点

xsync hbase-1.3.1/
2.1.6 HBase 服务的启动

1.启动方式

bin/hbase-daemons.sh start master
 bin/hbase-daemons.sh start regionserver

提示:如果集群之间的节点时间不同步,会导致 regionserver 无法启动,抛出ClockOutOfSyncException 异常。
2. 启动方式 2

bin/start-hbase.sh

对应的停止服务

bin/stop-hbase.sh
  1. 查看页面:http://hadoop104:16010

2.2 HBase Shell 操作

2.2.1 基本操作
  1. 进入 HBase 客户端命令行
bin/hbase shell
  1. 查看帮助命令: hbase(main):001:0> help
  2. 查看当前数据库中有哪些表 hbase(main):002:0> list
2.2.2 表的操作
  1. 创建表 hbase(main):002:0> create 'student','info'
  2. 插入数据到表
hbase(main):003:0> put 'student','1001','info:sex','male'
hbase(main):004:0> put 'student','1001','info:age','18'
hbase(main):005:0> put 'student','1002','info:name','Janna'
hbase(main):006:0> put 'student','1002','info:sex','female'
hbase(main):007:0> put 'student','1002','info:age','20'
  1. 扫描查看表数据
hbase(main):008:0> scan 'student'
hbase(main):009:0> scan 'student',{STARTROW => '1001', STOPROW => 
'1001'}
hbase(main):010:0> scan 'student',{STARTROW => '1001'}
  1. 查看表结构 hbase(main):011:0> describe ‘student’
  2. 更新指定字段的数据
hbase(main):012:0> put 'student','1001','info:name','Nick'
hbase(main):013:0> put 'student','1001','info:age','100'
  1. 查看“指定行”或“指定列族:列”的数据
hbase(main):014:0> get 'student','1001'
hbase(main):015:0> get 'student','1001','info:name'
  1. 统计表数据行数 hbase(main):021:0> count 'student'
  2. 删除数据
    删除某 rowkey 的全部数据:
hbase(main):016:0> deleteall 'student','1001'

删除某 rowkey 的某一列数据

hbase(main):017:0> delete 'student','1002','info:sex'
  1. 清空表数据 hbase(main):018:0> truncate 'student' 提示:清空表的操作顺序为先 disable,然后再 truncate。
  2. 删除表
    首先需要先让该表为 disable 状态:
hbase(main):019:0> disable 'student'

然后才能 drop 这个表:

hbase(main):020:0> drop 'student'

提示:如果直接 drop 表,会报错:ERROR: Table student is enabled. Disable it first.

  1. 变更表信息 将 info 列族中的数据存放 3 个版本:
hbase(main):022:0> alter 'student',{NAME=>'info',VERSIONS=>3}
hbase(main):022:0> get 'student','1001',{COLUMN=>'info:name',VERSIONS=>3}

3 HBase 进阶

3.1 架构原理

HBase详细架构图

hbase22端口拒绝连接 hbase 16000端口_大数据_05

1)StoreFile
保存实际数据的物理文件,StoreFile 以 HFile 的形式存储在 HDFS 上。每个 Store 会有一个或多个 StoreFile(HFile),数据在每个 StoreFile 中都是有序的。
2)MemStore
写缓存,由于 HFile 中的数据要求是有序的,所以数据是先存储在 MemStore 中,排好序后,等到达刷写时机才会刷写到 HFile,每次刷写都会形成一个新的 HFile。
3)WAL
由于数据要经 MemStore 排序后才能刷写到 HFile,但把数据保存在内存中会有很高的概率导致数据丢失,为了解决这个问题,数据会先写在一个叫做 Write-Ahead logfile 的文件中,然后再写入 MemStore 中。所以在系统出现故障的时候,数据可以通过这个日志文件重建.

3.2 写流程

hbase22端口拒绝连接 hbase 16000端口_nosql_06


写流程

1)Client 先访问 zookeeper,获取 hbase:meta 表位于哪个 Region Server。

2)访问对应的 Region Server,获取 hbase:meta 表,根据读请求的 namespace:table/rowkey,

查询出目标数据位于哪个 Region Server 中的哪个 Region 中。并将该 table 的 region 信息以

及 meta 表的位置信息缓存在客户端的 meta cache,方便下次访问。

3)与目标 Region Server 进行通讯;

4)将数据顺序写入(追加)到 WAL;

5)将数据写入对应的 MemStore,数据会在 MemStore 进行排序;

6)向客户端发送 ack;

7)等达到 MemStore 的刷写时机后,将数据刷写到 HFile.

3.3 MemStore Flush

hbase22端口拒绝连接 hbase 16000端口_hbase_07


MemStore 刷写时机

  1. 当某个 memstroe 的大小达到了 hbase.hregion.memstore.flush.size(默认值 128M), 其 所在 region 的所有 memstore 都会刷写 。 当 memstore 的大小达到了hbase.hregion.memstore.flush.size(默认值 128M) *(乘) hbase.hregion.memstore.block.multiplier(默认值 4)时,会阻止继续往该 memstore 写数据。
  2. 当 region server 中 memstore 的总大小达到java_heapsize*hbase.regionserver.global.memstore.size(默认值 0.4) hbase.regionserver.global.memstore.size.lower.limit(默认值 0.95),region 会按照其所有 memstore 的大小顺序(由大到小)依次进行刷写。直到 region server中所有 memstore 的总大小减小到上述值以下。 当 region server 中 memstore 的总大小达到 java_heapsizehbase.regionserver.global.memstore.size(默认值 0.4)时,会阻止继续往所有的 memstore 写数据。
  3. 到达自动刷写的时间,也会触发 memstore flush。自动刷新的时间间隔由该属性进行
    配置 hbase.regionserver.optionalcacheflushinterval(默认 1 小时)。
    4.当 WAL 文件的数量超过 hbase.regionserver.max.logs,region 会按照时间顺序依次进行刷写,直到 WAL 文件数量减小到 hbase.regionserver.max.log 以下(该属性名已经废弃,现无需手动设置,最大值为 32)。

刷盘的影响
memstore在不同的条件下会触发数据刷盘,那么整个数据在刷盘过程中,对region的数据写入等有什么影响?
memstore的数据刷盘,对region的直接影响就是:在数据刷盘开始到结束这段时间内,该region上的访问都是被拒绝的,这里主要是因为在数据刷盘结束时,RS会对改region做一个snapshot,同时HLog做一个checkpoint操作,通知ZK哪些HLog可以被移到.oldlogs下。从前面图上也可以看到,在memstore写盘开始,相应region会被加上UpdateLock锁,写盘结束后该锁被释放。

3.4 读流程

hbase22端口拒绝连接 hbase 16000端口_hbase22端口拒绝连接_08


读流程

1)Client 先访问 zookeeper,获取 hbase:meta 表位于哪个 Region Server。

2)访问对应的 Region Server,获取 hbase:meta 表,根据读请求的 namespace:table/rowkey,查询出目标数据位于哪个 Region Server 中的哪个 Region 中。并将该 table 的 region 信息以及 meta 表的位置信息缓存在客户端的 meta cache,方便下次访问。

3)与目标 Region Server 进行通讯;

4)分别在 Block Cache(读缓存),MemStore 和 Store File(HFile)中查询目标数据,并将查到的所有数据进行合并。此处所有数据是指同一条数据的不同版本(time stamp)或者不同的类型(Put/Delete)。

5) 将从文件中查询到的数据块(Block,HFile 数据存储单元,默认大小为 64KB)缓存到Block Cache。

6)将合并后的最终结果返回给客户端。

3.5 StoreFile Compaction

由于memstore每次刷写都会生成一个新的HFile,且同一个字段的不同版本(timestamp)和不同类型(Put/Delete)有可能会分布在不同的 HFile 中,因此查询时需要遍历所有的 HFile。为了减少 HFile 的个数,以及清理掉过期和删除的数据,会进行 StoreFile Compaction。

Compaction 分为两种,分别是 Minor Compaction 和 Major Compaction。Minor Compaction会将临近的若干个较小的 HFile 合并成一个较大的 HFile,但不会清理过期和删除的数据。Major Compaction 会将一个 Store 下的所有的 HFile 合并成一个大 HFile,并且会清理掉过期和删除的数据。

hbase22端口拒绝连接 hbase 16000端口_hbase_09

3.6 Region Split

默认情况下,每个 Table 起初只有一个 Region,随着数据的不断写入,Region 会自动进行拆分。刚拆分时,两个子 Region 都位于当前的 Region Server,但处于负载均衡的考虑,HMaster 有可能会将某个 Region 转移给其他的 Region Server。

Region Split 时机:

1.当1个region中的某个Store下所有StoreFile的总大小超过hbase.hregion.max.filesize, 该 Region 就会进行拆分(0.94 版本之前)。

2. 当 1 个 region 中 的 某 个 Store 下所有 StoreFile 的 总 大 小 超 过 Min(R^2 *

“hbase.hregion.memstore.flush.size”,hbase.hregion.max.filesize"),该 Region 就会进行拆分,其中 R 为当前 Region Server 中属于该 Table 的个数(0.94 版本之后)。

一个较大的region通过split操作,会生成两个小的region,称之为Daughter,一般Daughter中的数据是根据rowkey的之间点进行切分的,region的split过程大致如下图:

hbase22端口拒绝连接 hbase 16000端口_nosql_10


1)region先更改ZK中该region的状态为SPLITING。

2)Master检测到region状态改变。

3)region会在存储目录下新建.split文件夹用于保存split后的daughter region信息。

4)Parent region关闭数据写入并触发flush操作,保证所有写入Parent region的数据都能持久化。

5)在.split文件夹下新建两个region,称之为daughter A、daughter B。

6)Daughter A、Daughter B拷贝到HBase根目录下,形成两个新的region。

7)Parent region通知修改.META.表后下线,不再提供服务。

8)Daughter A、Daughter B上线,开始向外提供服务。

9)如果开启了balance_switch服务,split后的region将会被重新分布。

其实,split只是简单的把region从逻辑上划分成两个,并没有涉及到底层数据的重组,split完成后,Parent region并没有被销毁,只是被做下线处理,不再对外部提供服务。而新产生的region Daughter A和Daughter B,内部的数据只是简单的到Parent region数据的索引,Parent region数据的清理在Daughter A和Daughter B进行major compact以后,发现已经没有到其内部数据的索引后,Parent region才会被真正的清理。