HBase是依赖Hadoop的。为什么HBase能存储海量的数据?因为HBase是在HDFS的基础之上构建的,HDFS是分布式文件系统。HBase在HDFS之上提供了高并发的随机写和支持实时查询,这是HDFS不具备的。
Hbase的列族存储
这张表我们有两个列族,分别是UserInfo和OrderInfo。在UserInfo下有两个列,分别是UserInfo:name和UserInfo:age,在OrderInfo下有两个列,分别是OrderInfo:orderId和OrderInfo:money,这些数据的主键(RowKey)为1。
数据写到HBase的时候都会被记录一个时间戳,这个时间戳被我们当做一个版本。比如说,我们修改或者删除某一条的时候,本质上是往里边新增一条数据,记录的版本加一了而已。
Hbase的key-value
Key由RowKey(行键)+ColumnFamily(列族)+Column Qualifier(列修饰符)+TimeStamp(时间戳--版本)+KeyType(类型)组成,而Value就是实际上的值。
对比上面的例子,其实很好理解,因为我们修改一条数据其实上是在原来的基础上增加一个版本的,那我们要准确定位一条数据,那就得(RowKey+Column+时间戳)。
KeyType是什么?我们上面只说了「修改」的情况,你们有没有想过,如果要删除一条数据怎么做?实际上也是增加一条记录,只不过我们在KeyType里边设置为“Delete”就可以了。
Hbase的架构
1、Client客户端,它提供了访问HBase的接口,并且维护了对应的cache来加速HBase的访问。
2、Zookeeper存储HBase的元数据(meta表)索引,无论是读还是写数据,都是去Zookeeper里边拿到meta元数据的索引告诉给客户端去哪台机器读写数据。
3、HRegionServer它是处理客户端的读写请求,负责与HDFS底层交互,是真正干活的节点。
总结大致的流程就是:client请求到Zookeeper,然后Zookeeper返回HRegionServer地址给client,client得到Zookeeper返回的地址去请求HRegionServer,HRegionServer读写数据后返回给client。
HRegionSever内部
HBase一张表的数据会分到多台机器上的。那HBase是怎么切割一张表的数据的呢?用的就是RowKey来切分,其实就是表的横向切割。
说白了就是一个HRegion上,存储HBase表的一部分数据。一个列族的内容都是存储在一个store中的,因此Hbase可以说是基于列族进行存储的。
在store内部HBase在写数据的时候,会先写到Mem Store,当MemStore超过一定阈值,就会将内存中的数据刷写到硬盘上,形成StoreFile,而StoreFile底层是以HFile的格式保存,HFile是HBase中KeyValue数据的存储格式。
所以说:Mem Store我们可以理解为内存 buffer,HFile是HBase实际存储的数据格式,而StoreFile只是HBase里的一个名字。
Hlog的作用
由上述可知,Hbase写数据是先写在内存中的,因此为了防止机器宕机,内存的数据没刷到磁盘中就挂了。我们在写Mem store的时候还会写一份HLog,注意这里是在每个HRegionServer中有一个HLog,记录该HRegionServer中每个HRegion的log信息进行宕机恢复。
- HRegionServer是真正干活的机器(用于与hdfs交互),我们HBase表用RowKey来横向切分表
- HRegion里边会有多个Store,每个Store其实就是一个列族的数据(所以我们可以说HBase是基于列族存储的)
- Store里边有Men Store和StoreFile(HFile),其实就是先走一层内存,然后再刷到磁盘的结构
掌管全局的HMaster
HMaster会处理 HRegion 的分配或转移。如果我们HRegion的数据量太大的话,HMaster会对拆分后的Region重新分配RegionServer。(如果发现失效的HRegion,也会将失效的HRegion分配到正常的HRegionServer中)
HMaster会处理元数据的变更和监控RegionServer的状态。
RowKey的设计
由于RowKey是会按字典序排序的,我们HBase表会用RowKey来横向切分表,进行查询的时候变可以使用二分的方式进行查询。