一、HBase简介
1、Apache HBase™是Hadoop数据库,是一个分布式,可扩展的大数据存储。
2、当您需要对大数据进行随机,实时读/写访问时,请使用Apache HBase™。 该项目的目标是托管非常大的表( 数十亿的行*百万的列 ) 在商品硬件集群上。 Apache HBase是一个开源的,分布式的,版本化的非关系数据库
3、利用Hadoop HDS 作为其文件存储系统,利用Hadoop MapReduce来处理HBASE中的海量数据,利用ZOOKEEPER作为其分布式协同服务
4、主要用来存储非结构化和半结构化的松散数据
二、HBASE数据模型
1、Rowkey
rowkey类似于关系型数据库的主键,是一行记录的唯一标识。
rowkey是按照字典序自动排序的
rowkey只能存储64K的字节数据
2、Column Family列族 (CF)
HBase表中的每个列都归属于某个列族,列族必须作为表模式(schema)定义的一部分预先给出。如 create ‘test’, ‘course’;
列名以列族作为前缀,每个“列族”都可以有多个列成员(column);如course:math, course:english, 新的列族成员(列)可以随后按需、动态加入;
权限控制、存储以及调优都是在列族层面进行的;
HBase把同一列族里面的数据存储在同一目录下,由几个文件保存。
3、Timestamp时间戳
在HBase一份数据有多个版本,根据唯一的时间戳来区分每个版本之间的差异,不同版本的数据按照时间倒序排序,最新的数据版本排在最前面。
时间戳的类型是64位整形
时间戳可以在数据写入时由HBase自动赋值也可以人员手动指定
4、cell单元格
cell单元格是由行和列的交叉坐标决定的
cell单元格是由版本的
cell单元格中的内容: 由{row key, column( =<family> +<qualifier>), version} 唯一确定的单元
cell中存储的数据是没有类型的,全部由字节数组组成,也就是说HBASE中的数据是没有类型的,全都是字节数组
三、HBase的预写日志(WAL)
因为HBase是实时读写的数据库,所以我们在操作数据的时候,会把数据先放在内存中,当内存中的数据达到一定量的时候才会落盘。但数据放在内存中是有一定的风险的,比如掉电之后,内存中的数据就会丢失。为了防止这种情况,HBase中加入了WAL(write ahead log)预写日志机制,每个数据的写入操作(PUT/DELETE)执行前,必须先通过WAL记账。先将数据写入Hlog文件,如果写入失败,则写入操作失败。Hlog位于RegionServer中,每个RegionServer维护一个Hlog。
WAL的作用是灾难恢复,一旦服务器崩溃,或者数据被误删,则通过log日志重放,可以恢复事故数据。
WAL如此重要,所以默认是开启的
四。HBase架构
HBase架构的角色:
1、client
包含HBase的接口并维护cache来加快对hbase的访问
2、zookeeper
保证任何时候,集群中只有一个活跃的HMaster
存储所有的Region的寻址入口
实时监控所有HRegionServer的上下线消息,并通知HMaster
3、HMaster
HMaster是没有单点故障的,因为集群中可以有多个HMaster,但是通过zookeeper的分布式协同服务保障有且只有一个活跃的HMaster对外提供服务。
HMaster负责为RegionServer分配region。
负责RegionServer的负载均衡。
发现失效的RegionServer并重新分配其上的region。
管理用户对table的增删改操作。
4、HRegionServer
RegionServer维护Region,处理对这些Region的I/O请求。
RegionServer负责切分在运行过程中逐渐变得过大的region。
HRegionServer中的组件
1、region
HBase自动把表水平划分成多个区域(region),每个region会保存一个表里面某段连续的数据。也就是说一个大表被切成很多小份,每个小份是一个region。
每个表一开始只有一个region,随着数据的不断插入,region不断增大。当region增大到某个阈值的时候,region就会等分为两个新的region(裂变)。
当table中的行不断增多,就会有越来越多的region。这样,一张完整的表就被 保存在多个RegionServer上。
region是HBase中分布式存储和负载均衡的最小单元。最小单元就表示不同的region可以分布在不同的HRegionServer上。
2、store
一个region有多个store组成,每个store对应一个CF(列族)。
store中包含位于内存中的memstore和位于磁盘的storefile。
3、memstore与storefile
每当进行写操作时,写操作会先进入memstore,当memstore中的数据到达某个阈值,HRegionServer会启动flashcache进程将数据写到storefile,每次写入形成一个单独的storefile。
当storefile文件数量达到一定阈值后,系统会进行合并,在合并过程中会进行版本合并和删除工作,形成各大的storefile。
当一个region所有的storefile的大小和数量达到一定的阈值后,会把当前的region分割为两个,并有HMaster分配到不同的RegionServer服务器,实现负载均衡。
storefile以Hfile的格式存储在HDFS上。
客户端检索数据,先到memstore中找,找不到再到blockcache,再找不到去storefile
五、HBase的读写流程(0.98以后版本)
写请求
客户端在进行写请求的时候。首先会访问zookeeper,因为zookeeper中存储着HBase元数据(meta)所在节点的信息(HBase的元数据在某个RegionServer中存储,但是存储元数据的RegionServer的信息保存在zookeeper中)。客户端拿到元数据所在节点后访问相应节点的RegionServer拿到元数据。最后根据元数据找到要操作的region。但是,找到region后不是先往memstore中写。而是要先写入WAL(预写日志)的hlog中(写入hlog成功后,会有一个异步侧线程sync(),这个线程会实时检测hlog中有没有数据,如果有,直接落盘),只有往hlog中写入成功了,才能接着往memstore中写。
当memstore中的数据到达某个阈值,HRegionServer会启动flashcache进程将数据写到storefile,每次写入形成一个单独的storefile。
当storefile文件数量达到一定阈值后,系统会进行合并,在合并的时候会对数据排序,同时在合并过程中会进行版本合并和删除工作,形成各大的storefile。
合并的方式有两种,分别是minor和major。minor默认是3~10个storefile进行合并。major则是将当前目录下的所有的storefile合并。注意:在文件合并的时候是不提供服务的。
因为minor是3~10个文件进行合并,所以占用资源少,速度快。所以我们一般使用minor。而major因为熟读慢,所以我们一般不用,用也是手动进行。
当一个region所有的storefile的大小和数量达到一定的阈值后,会把当前的region分割为两个,并有HMaster分配到不同的RegionServer服务器,实现负载均衡。
读请求
客户端在进行读请求的时候。寻找region的过程几乎与写请求相同。首先在zookeeper中找元数据在哪个RegionServer中存储,然后找到RegionServer拿到元数据,然后根据元数据找相应的region。
在region中寻找数据的过程如下:首先,会在region的memstore中寻找,如果被查找的记录是刚刚通过写请求写入的,还没被写入storefile,那么查找成功。如果没有找到,则到blockcache(读缓存)中找,找到返回。找不到会继续深入到storefile中查找,注意:如果是在storefile中找到的,并不会立即返回,而是要先将数据写入blockcache中(方便下次查找),写入成功后返回数据。
但是,这样存在一个问题,那就是随着读请求的增多,blockcache会不断变大。为了防止这种情况,系统采用最近最少使用算法(LRU)来维护blockcache。
blockcache位于RegionServer中,一个RegionServer维护一个blockcache。