全称Hadoop Database,是google Bigtable的开源实现
1. HBase-组件构成
-
Master:通常运行在NameNode上
-
Master是集群的主节点,本质是一个进程
-
负责管理元数据,如定期更新hbase::meta表
-
分配与移动region保证集群的负载
-
管理RegionServer,出现问题时进行故障转移
-
-
region server
-
负载region的合并与拆分
-
负载数据的增删改查
-
将MemStore中数据写到StoreFiles中
-
检查RegionServer的Hlog文件
-
-
zooKeeper
-
协助选举Master
-
监听RegionServer的心跳,向master汇报RegionServer的信息
-
存放与维护集群配置信息,如hbase::meta表的地址信息
-
-
client
-
可以不经过master直接与RegionServer通信,发出读写请求,所以在master挂掉的情况下集群仍然可以运行一段时间
-
-
storeFile
-
实际存储数据的物理文件,StoreFile存储在HDFS上,格式是HFile
-
2. HBase--架构体系
-
hbase::meta
-
以前叫(.META.),本质上也是一张hbase表,用于记录全部的region信息 例如存放在哪个RegionServer上
-
hbase::meta的地址信息存放在ZooKeeper中
-
-
Meta Cache
-
客户端中的元数据缓存,记录了table的region信息,以及hbase::meta地址信息,方便后续查询
-
-
Block Cahce
-
读缓存,缓存了从HDFS中读取的数据,方便下次查询使用
-
-
WAL
-
也称作HLog,预写入日志,记录了某一RegionServer中所有的数据变更,并以HFile 的形式存储在HDFS中
-
-
MemStore
-
向Store中写入数据时,数据会先存放在内存中的memStore中,等到flush时再写入到StoreFile中
-
flush的最小单位时region,也就是发生flush时,一个region中的所有store都会进行flush
-
3. HBase---架构原理
3.1MemStore flush
Flush: 写入Store的数据会首先保存在MemStore中(内存中),之后在某一时机才会持久化到磁盘上
发生flush时,同一region的所有memstore都会进行flush
3.1.1 flush的过程
1)发生flush时,当前的memstore被移动到快照中,并被清除
2)HBase重新创建一个MemStore继续提供服务
3)刷写结束后,将备份中的快照删除
3.1.2 触发flush的时机
1)单个MemStore容量超限
一个MemStore的大小超过128M(默认值)时,该region下的所有 MemStore都会flush
2)所有MemStore容量总和超限
一个RegionServer管理的所有region的所有MemStore所占的空间 大于堆内存的40%时,触发flush,此时所有的MemStore都进行刷 写,读写操作被阻塞
3)根据时长flush
由MemStore的最后一次编辑时间决定,默认最后一次编辑超过1小 时就进行flush
4)手动执行flush
3.1.3flush时删除数据
flush时会把过期数据删除掉,如果两条Row Key相同的数据先后写入MemStore,(一定要同时在一个内存中),那么flush时会把老的那条删掉,只flush最新的数据.
3.2 StoreFile Compaction
每次flush时,都会产生新的HFile文件,这样会产生许多小文件,并且同一个数据的不同版本可能会在不同的HFile中。
为了减少HFile的数量,以及清理过期和已删除的数据,HBase需要将HFile进行合并,这个过程成为Store Compaction
3.2.1 StorFile Compaction的类型
-
Minor Compaction
-
同一个Store下的HFile文件个数达到3个时会触发Minor Compaction
-
将临近的若干小HFile合成一个大HFile,并不会清理删除和过期的数据,并且原来的老HFile并不会立即删除,会等一段时间才被删除
-
-
Major Compaction
-
会将一个Store下的所有的HFile文件进行合并,并清理掉删除和过期的数据。
-
Major Compaction默认7天自动执行一次,生产中一般禁止自动执行。因为非常消耗资源,一般在空闲时手动执行
-
3.3 Region Split
当一个table表项不断增加,似的一个region变得过大,这时RegionServer就需要对region进行拆分
3.3.1 split的过程
region的拆分在RegionServer上独立进行,主机不参与
-
从region中选择某个row key作为分割点
-
刚拆分时,新创建的子region不会立即写入数据。它创建了两个引用文件,引用文件指向被拆分region的两个不同部分
-
新region的信息添加到hbase:meta表中,处于负载均衡的考虑,Master可能会将Region转移给其他的Region Server
-
当发生compactions重写数据文件时,引用才会消失。如果子region不再引用父region的文件,父region才会被删除
4. HBase 数据模型
存储逻辑:rowKey -- cloumn family -- cloumn -- cloumn qualifier -- timestamlp -- cell
类似于关系数据库将HBase table类比的放在一张表中
-
rowKey:相当于关系型数据库中的主键,rowKey是唯一的,如果重复插入rowKey相当于覆盖
-
column family:是一组列的集合,HBase一般有1-3个列族
-
column:是具体的一列,由列族和列限定符表示。如 personal_info:name表示name那一列
-
column qualifier:相当于是列名,创建时不必须指定,HBase中列可以动态增加指的就是列限定符可以动态增加
-
time stamp:写入数据时,每个数据都会加上一个时间戳,默认是数据写入HBase的时间。新数据覆盖老数据时,不是直接把老数据删掉,而是只显示时间戳更大的那条数据。
-
cell:是HBase中最小存储单位,由{rowKey : cloumn family : column qualifier : time stamp}唯一确定。cell中数据没有类型,都是字节码存储,当cell没有数据时,不会占用空间(与关系型数据库不同)
重要概念
-
Name Space
相当于关系数据库中的DataBase,每个命名空间下可以有多个表,HBase自带两个命名空间hbase和default,hbase存放HBase内置表,default是用户默认使用的空间
-
Region
根据rowKey划分的一个表的切片,不同的region存储在不同的节点上
-
Store
HBase表通过cloumn family划分为不同的store,region一般等数据量大了才会split,而store一开始就划分
有几个Store就会将数据存储在几个文件中。
5. HBase读写流程
读数据流程
分为两大步7小步
-
获取region位置
-
Clinet访问zooKeeper,获取元数据表hbase::meta的存储位置
-
访问存放meta的目标regionServer,读取habse::meta表,并根据请求的table/rowKey信息得到目标数据是在哪个RegionServer下的region中
-
将table的region信息与hbase:meta表的位置信息缓存在客户端的meta cache,方便下次访问
-
-
读取目标数据
-
Client向得到的目标RegionServer发出Get请求
-
分别在Block Cache、MemStore、StoreFile中查找数据,因为同一个数据可能存在不同的版本,比较各个版本返回最新的
-
如果在Block Cache中查到数据,就不不用查磁盘中的文件了,如果从StoreFile中找到数据,则将其缓存到Block Cache中
-
比较Block Cache的数据和MemStore中的数据(都在内存中),将最中结果返回给客户端
-
写数据流程
分为两大步7小步
-
获取目标与Region位置
i, ii, iii与读数据一致
如果meta cache中已经有缓存,可以跳过这一步骤
-
写入目标数据
-
Client向目标RS发送put请求
-
先将数据写入WAL中
-
再将数据写入MemStore中,数据会在MemStore中进行排序
-
写入成功后返回ack给Clinet表示写入成功
-
总结
HBase的读比写慢,读取的过程会扫描磁盘文件。写入数据时,只要数据进了内存基本就完成了,后面的flush和Region Split会由别的线程来完成。
参考: