文章目录
- 一、HBase简介
- 1.1 HBase定义
- 1.2 HBase特点
- 1.3 HBase数据模型
- 1.4 HBase基本架构
- 1.5 HBase完整架构
- 1.6 HBase Meta表
- 二、HBase安装
- 三、HBase进阶原理
- 3.1 写流程
- 3.2 读流程
- 3.3 MemStore Flush
- 3.4 StoreFile Compaction
- 3.5 Region Split
一、HBase简介
1.1 HBase定义
HBase
是一种分布式、可扩展、支持海量数据存储的NoSQL
数据库。利用HBase
技术可在廉价PC Server
上搭建起大规模结构化存储集群。HBase
的目标是存储并处理大型的数据,更具体来说是仅需使用普通的硬件配置,就能够处理由成千上万的行和列所组成的大型数据。
1.2 HBase特点
- 海量存储
HBase
适合存储PB
级别的海量数据,在PB级别的数据以及采用廉价PC
存储的情况下,能在几十到百毫秒内返回数据。这与HBase
的极易扩展性息息相关。正式因为HBase
良好的扩展性,才为海量数据的存储提供了便利。 - 列式存储
这里的列式存储其实说的是列族(ColumnFamily
)存储,HBase
是根据列族来存储数据的。列族下面可以有非常多的列,列族在创建表的时候就必须指定。 - 极易扩展
HBase
的扩展性主要体现在两个方面,一个是基于上层处理能力(RegionServer
)的扩展,一个是基于存储的扩展(HDFS
)。通过横向添加RegionSever
的机器,进行水平扩展,提升HBase
上层的处理能力,提升HBase
服务更多Region
的能力。 - 高并发(多核)
由于目前大部分使用HBase
的架构,都是采用的廉价PC
,因此单个IO
的延迟其实并不小,一般在几十到上百ms
之间。这里说的高并发,主要是在并发的情况下,HBase
的单个IO
延迟下降并不多。能获得高并发、低延迟的服务。 - 稀疏
稀疏主要是针对HBase
列的灵活性,在列族中,你可以指定任意多的列,在列数据为空的情况下,是不会占用存储空间的。
1.3 HBase数据模型
逻辑上,HBase
的数据模型同关系型数据库很类似,数据存储在一张表中,有行有列。但从HBase
的底层物理存储结构(K-V
) 来看,HBase
更像是一个multi-dimensional map
。
①HBase逻辑结构
- 列族:
Hbase
是根据列族来存储数据的。列族下面可以有非常多的列,列族在创建表的时候就必须指定,不同的列族数据存储在不同的位置。通过列族可以将宽表进行拆分。 - Region:
Region
类似于分区,将同一张的数据进行拆分。通过Region
可以将高表进行拆分。 - Row key:类似于索引,
Row key
是有序的,根据字典顺序进行排序。 - 列:纵向数据
- store:数据存储在
store
中,一个store
对应HBase
表中的一个列族
②HBase物理存储结构
③数据模型
- Name Space
命名空间类似于关系型数据库的database
概念,每个命名空间下有多个表。Hbase
有两个自带的命名空间,分别是hbase
和default
,hbase
中存放的是HBase
内置的表,default
表是用户默认使用的命名空间。 - Region
类似于关系型数据库的表概念。不同的是,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, time Stamp}
唯一确定的单元。cell
中的数据是没有类型的,全部是字节码形式存贮。
1.4 HBase基本架构
不完整版:
RegionServer的作用
-
Data
(数据级别):get
,put
,delete
-
Region
:splitRegion
(切),compactRegion
(合)
Master的作用
-
Table
(表级别):create
,delete
,alter
-
RegionServer
:分配regions
到每 个RegionServer
,监控每个RegionServer
的状态。
1.5 HBase完整架构
从图中可以看出HBase
是由Client
、Zookeeper
、Master
、HRegionServer
、HDFS
等几个组件组成,下面来介绍一下几个组件的相关功能:
①Client
Client
包含了访问HBase
的接口,另外Client
还维护了对应的cache
来加速HBase
的访问,比如cache
的.META
元数据的信息。
②Zookeeper
HBase
通过Zookeeper
来做master
的高可用、RegionServer
的监控、元数据的入口以及集群配置的维护等工作。具体工作如下:
- 通过
Zookeeper
来保证集群中只有1个master
在运行,如果master
异常,会通过竞争机制产生新的master
提供服务 - 通过
Zookeeper
来监控RegionServer
的状态,当RegionServer
有异常的时候,通过回调的形式通知master
、RegionServer
上下线的信息 - 通过
Zookeeper
存储元数据的统一入口地址
③HMaster(类似NameNode)
master
节点的主要职责如下:
- 为
RegionServer
分配Region
- 维护整个集群的负载均衡
- 维护集群的元数据信息
- 发现失效的
Region
,并将失效的Region
分配到正常的RegionServer
上 - 当
RegionServer
失效的时候,协调对应Hlog
的拆分
④HregionServer(类似DataNode)
HregionServer
直接对接用户的读写请求,是真正的“干活”的节点。它的功能概括如下:
- 管理
master
为其分配的Region
- 处理来自客户端的读写请求
- 负责和底层
HDFS
的交互,存储数据到HDFS
- 负责
Region
变大以后的拆分 - 负责
Storefile
的合并工作
⑤HDFS
HDFS
为HBase
提供最终的底层数据存储服务,同时为HBase
提供高可用(Hlog
存储在HDFS
)的支持,具体功能概括如下:
- 提供元数据和表数据的底层分布式存储服务
- 数据多副本,保证的高可靠和高可用性
⑥Region
HBase
表的分片,HBase
表会根据RowKey
值被切分成不同的region存储在RegionServer
中,在一个RegionServer
中可以有多个不同的Region
。
⑦HFile
这是在磁盘上保存原始数据的实际的物理文件,是实际的存储文件。StoreFile
是以HFile
的形式存储在HDFS
的。
⑧Store
HFile
存储在Store
中,一个Store
对应HBase
表中的一个列族。
⑨MemStore
内存存储存当前的数据操作,所以当数据保存在WAL
中之后,RegsionServer
会在内存中存储键值对。
⑩WAL(Write-Ahead logs)
当对HBase
读写数据的时候,数据不是直接写进磁盘,它会在内存中保留一段时间(时间以及数据量阈值可以设定)。但把数据保存在内存中可能有更高的概率引起数据丢失,为了解决这个问题,数据会先写在一个叫做Write-Ahead logfile
的文件中,然后再写入内存中。所以在系统出现故障的时候,数据可以通过这个日志文件重建。
1.6 HBase Meta表
HBase
有一个叫做Meta
的特殊的目录表,用于保存集群中Regions
的位置信息(Region
列表)。ZooKeeper
存储着Meta
表的位置。
二、HBase安装
前提:Hadoop
集群和ZooKeeper
集群的正常启动。
①HBase
的解压
[root@hadoop100 software]# tar -zxvf hbase-1.3.1-bin.tar.gz -C /opt/module
②修改hbase-env.sh
export JAVA_HOME=/opt/module/jdk1.8.0_144
export HBASE_MANAGES_ZK=false
③修改hbase-site.xml
<property>
<name>hbase.rootdir</name>
<value>hdfs://hadoop100:9000/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>hadoop100:2181,hadoop101:2181,hadoop102:2181</value>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/opt/module/zookeeper-3.4.10/zkData</value>
</property>
④修改regionservers
hadoop100
hadoop101
hadoop102
⑤软连接hadoop
配置文件到hbase
[root@hadoop100 module]# ln -s /opt/module/hadoop-2.7.2/etc/hadoop/core-site.xml
/opt/module/hbase-1.3.1/conf/core-site.xml
[root@hadoop100 module]# ln -s /opt/module/hadoop-2.7.2/etc/hadoop/hdfs-site.xml
/opt/module/hbase-1.3.1/conf/hdfs-site.xml
⑥分发HBase
[root@hadoop100 module]# xsync hbase-1.3.1
⑦HBase
服务的启动
启动方式1:
[root@hadoop100 module]# bin/hbase-daemon.sh start master
[root@hadoop100 module]# bin/hbase-daemon.sh start regionserver
启动方式2:
[root@hadoop100 hbase-1.3.1]$ bin/start-hbase.sh
停止:
[root@hadoop100 hbase-1.3.1]$ bin/stop-hbase.sh
提示:如果集群之间的节点时间不同步,会导致regionserver
无法启动,抛出ClockOutOfSyncException
异常。
解决①(推荐):集群内时间同步:参考
解决②:hbase-site.xml
中属性:hbase.master.maxclockskew
设置更大的值
<property>
<name>hbase.master.maxclockskew</name>
<value>180000</value>
<description>Time difference of regionserver from master</description>
</property>
启动成功后,访问http://hadoop102:16010
进入HBase
管理页面:
三、HBase进阶原理
3.1 写流程
-
Client
先访问ZooKeeper
,获取hbase:meta
表位于哪个RegionServer
; - 访问对应的
RegionServer
,获取hbase:meta
表,根据读请求的namespace:table/rowkey
,查询出目标数据位于哪个Region Server
中的哪个Region
中。并将该table
的region
信息以及meta
表的位置信息缓存在客户端的meta cache
,方便下次访问; - 与目标
RegionServer
进行通讯; - 将数据顺序写入(追加)到
WAL
; - 将数据写入对应的
MemStore
,数据会在MemStore
进行排序; - 向客户端发送
ack
; - 等达到
MemStore
的刷写时机后,将数据刷写到HFile
。
3.2 读流程
-
Client
先访问ZooKeeper
,获取hbase:meta
表位于哪个RegionServer
; - 访问对应的
RegionServer
,获取hbase:meta
表,根据读请求的namespace:table/rowkey
,查询出目标数据位于哪个Region Server
中的哪个Region
中。并将该table
的region
信息以及meta
表的位置信息缓存在客户端的meta cache
,方便下次访问; - 查询数据,如果
Block Cache
没有对应数据,同时读取内存(MemStore
)和磁盘(StoreFile
)中的数据(并将磁盘的数据缓存到Block Cache
,LRU
算法),比较时间戳返回对应的数据。 - 如果
Block Cache
有对应数据,直接比较和MemStore
中数据的最大时间戳,返回该数据。
3.3 MemStore Flush
MemStore
数据达到阈值,将数据刷到硬盘。将内存中的数据删除,同时删除HLog
中的历史数据。
MemStore
刷写时机:
- 当某个
MemStore
的大小达到了hbase.hregion.memstore.flush.size
(默认值128M
),其所在Region
的所有MemStore
都会刷写。 -
RegionServer
中的MemStore
大小超过hbase.regionserver.global.memstore.size
(默认大小为堆大小的40%) - 到达自动刷写的时间也会触发
MemStore
Flush
,自动刷新的时间间隔由该属性进行配置hbase.regionserver.optionalcacheflushinterval
(默认1小时)。
3.4 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
,并且会清理掉过期和删除的数据。
StoreFile Compaction
触发时机:当数据块达到 4 块,Hmaster
触发合并操作,Region
将数据块加载到本地,进行合并;当合并的数据超过 256M
,进行拆分,将拆分后的Region
分配给不同的HRegionServer
管理(一个表中的Region
就会被不同的HRegionServer
管理,分布式存储,高可用容灾); 当 HRegionServer
宕机后,将 HRegionServer
上的HLog
拆分,然后分配给不同的HRegionServer
加载,修改.META.
;
3.5 Region Split
默认情况下,每个Table
起初只有一个Region
,随着数据的不断写入,Region
会自动进行拆分。刚拆分时,两个子Region
都位于当前的Region Server
,但处于负载均衡的考虑,HMaster
有可能会将某个Region
转移给其他的RegionServer
。
Region Split
时机:
- 当1个
Region
中的某个Store
下所有StoreFile
的总大小超过hbase.hregion.max.filesize
,该Region
就会进行拆分(0.94 版本之前)。 - 当1个
Region
中的某个Store
下所有StoreFile
的总大小超过Min(R^2 * "hbase.hregion.memstore.flush.size",hbase.hregion.max.filesize")
,该Region
就会进行拆分,其中R
为当前Region Server
中属于该Table
的个数(0.94 版本之后)。