注:本文内容均不是原创,但是是我从多篇文章中摘录结合而成,中间也插入了一些我的个人理解  --- 季义钦

参考文献:

1 http://blog.csdn.net/woshiwanxin102213/article/details/17584043

2 http://www.searchtb.com/2011/01/understanding-hbase.html


(一)Hbase简介

HBase – Hadoop Database,是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群。

HBase是Google Bigtable的开源实现,类似Google Bigtable利用GFS作为其文件存储系统,HBase利用Hadoop HDFS作为其文件存储系统;Google运行MapReduce来处理Bigtable中的海量数据,HBase同样利用Hadoop MapReduce来处理HBase中的海量数据;Google Bigtable利用 Chubby作为协同服务,HBase利用Zookeeper作为对应。


上图描述了Hadoop EcoSystem中的各层系统,其中HBase位于结构化存储层,Hadoop HDFS为HBase提供了高可靠性的底层存储支持,Hadoop MapReduce为HBase提供了高性能的计算能力,Zookeeper为HBase提供了稳定服务和failover机制。

此外,Pig和Hive还为HBase提供了高层语言支持,使得在HBase上进行数据统计处理变的非常简单。 Sqoop则为HBase提供了方便的RDBMS数据导入功能,使得传统数据库数据向HBase中迁移变的非常方便。


(二)HBase访问接口

1.       Native Java API,最常规和高效的访问方式,适合Hadoop MapReduce Job并行批处理HBase表数据

2.       HBase Shell,HBase的命令行工具,最简单的接口,适合HBase管理使用

3.       Thrift Gateway,利用Thrift序列化技术,支持C++,PHP,Python等多种语言,适合其他异构系统在线访问HBase表数据

4.       REST Gateway,支持REST 风格的Http API访问HBase, 解除了语言限制

5.       Pig,可以使用Pig Latin流式编程语言来操作HBase中的数据,和Hive类似,本质最终也是编译成MapReduce Job来处理HBase表数据,适合做数据统计

6.       Hive,当前Hive的Release版本尚没有加入对HBase的支持,但在下一个版本Hive 0.7.0中将会支持HBase,可以使用类似SQL语言来访问HBase


(三)HBase存储模型

1、先看Hbase中针对一个表的相关基本概念:

RowKey:是Byte array,是表中每条记录的“主键”,方便快速查找,Rowkey的设计非常重要,因为根据rowkey查找数据效率极高。
Column Family:列族,拥有一个名称(string),包含一个或者多个相关列,创建一个表的时候列族要事先定义并不能动态更改,类似关系数据库的Schema
Column:属于某一个columnfamily,familyName:columnName,每个列族中的列无需事先定义,可动态增加(HBase表动态拓展的关键)
Version Number:类型为Long,默认值是系统时间戳,可由用户自定义
Value(Cell):Byte array


2、下面来看HBase的逻辑模型:


可以看到每一行都有一个rowkey作为主键唯一标识一行,并且列族是固定的。

同一个列族,但是不同的行,所包含的列并不一样,只存储有值的列。

每一个值可能有多个版本,默认以时间戳作为区分。

所有值都是以字节数组的形式被存储。


为什么Hbase中根据rowkey查找指定表的指定列族的指定列的值很快?

因为HBase 为每个值维护了多级索引,即:<key, column family, column qualifier, timestamp>

即四维坐标定位一个数据单元,如果把这个四维坐标看做一个整体,那么HBase就可以认为是一个键值系统。


当然键也可以变化,如果键是<key, column family, column qualifier>,那么对应的值就是一个集合,这个集合中是该数据单元的多个版本。

如果把<key, column family>看做键,那么值就是集合的集合。。。


3、物理上如何存储(HRegion,Store,MemStore,StoreFile,HFile,HLog):

(1) Table中所有行都按照row key的字典序排列;

(2) Table按照行被分割为多个Region。当Table随着记录数不断增加而变大后,会逐渐分裂成多份splits,成为regions,一个region由[startkey,endkey)表示,不同的region会被Master分配给相应的RegionServer进行管理。

(3) Region按大小分割的,每个表开始只有一个Region,随着数据增多,Region不断增大,当增大到一个阀值的时候,Region就会等分会两个新的Region,之后会有越来越多的Region;

(4) Region是Hbase中分布式存储和负载均衡的最小单元,不同Region分布到不同RegionServer上。


(5) Region虽然是分布式存储的最小单元,但并不是存储的最小单元。HRegion由一个或者多个Store组成:


Store存储是HBase存储的核心了,其中由两部分组成,一部分是MemStore,一部分是StoreFiles。

(1)MemStore缓存用户写入的数据:

MemStore是Sorted Memory Buffer,用户写入的数据首先会放入MemStore。

(2)StoreFile最终存储这些数据:

当MemStore满了以后会Flush成一个StoreFile(底层实现是HFile),当StoreFile文件数量增长到一定阈值,会触发Compact合并操作,将多个StoreFiles合并成一个StoreFile,合并过程中会进行版本合并和数据删除,因此可以看出HBase其实只有增加数据,所有的更新和删除操作都是在后续的compact过程中进行的,这使得用户的写操作只要进入内存中就可以立即返回,保证了HBase I/O的高性能。当StoreFiles Compact后,会逐步形成越来越大的StoreFile,当单个StoreFile大小超过一定阈值后,会触发Split操作,同时把当前Region Split成2个Region,父Region会下线,新Split出的2个孩子Region会被HMaster分配到相应的HRegionServer上,使得原先1个Region的压力得以分流到2个Region上。


关于列族的存储:

每个HStore对应了Table中的一个Column Family的存储,每个Column Family其实就是一个集中的存储单元,因此最好将具备共同IO特性的column放在一个Column Family中,这样最高效。

我理解这句话的意思是这样的: 不论是Region,Store,还是构成Store的一个MemStore和多个StoreFile,他们都是逻辑上的概念,在HBase中都描述为一个类,最终真实存储数据的物理存储对象是HDFS上的HFile。

一个Store对应一个列族,意思就是一个特定的列族是用一个Store对象描述,通过这个Store对象可以访问到这个列族的所有信息。


一个列族对应于一个HStore,其中又包含一个写缓存MemStore,多个存储数据的HFile,实际上还有一个读缓存BlockCache。

一个列族在存储到其HStore的时候,是先写满一个HFile,再写下一个HFile。所以针对任意一行,其一个列族的数据必定存储在一个HFile文件中,所以说访问一个列族的数据比较高效。另外任意一行的所有列族的数据一定存储在一个region中。


HBase是面向列的数据库:列族 中的每一列,若没有数据则不会存储。

HBase是按列族存储的数据库: 一行中 同一个列族中的数据必定存放在一起(一个HFile中)。


HLog用于防止写入MemStore的数据丢失:

在分布式系统环境中,无法避免系统出错或者宕机,因此一旦HRegionServer意外退出,MemStore中的内存数据将会丢失,这就需要引入HLog了。每个HRegionServer中都有一个HLog对象,HLog是一个实现Write Ahead Log的类,在每次用户操作写入MemStore的同时,也会写一份数据到HLog文件中(HLog文件格式见后续),HLog文件定期会滚动出新的,并删除旧的文件(已持久化到StoreFile中的数据)。当HRegionServer意外终止后,HMaster会通过Zookeeper感知到,HMaster首先会处理遗留的 HLog文件,将其中不同Region的Log数据进行拆分,分别放到相应region的目录下,然后再将失效的region重新分配,领取 到这些region的HRegionServer在Load Region的过程中,会发现有历史HLog需要处理,因此会Replay HLog中的数据到MemStore中,然后flush到StoreFiles,完成数据恢复。


备注:上面提到两个概念,即HFile和HLog,HBase中的所有数据文件都存储在Hadoop HDFS文件系统上,主要包括这两种文件类型:

1.       HFile, HBase中KeyValue数据的存储格式,HFile是Hadoop的二进制格式文件,实际上StoreFile就是对HFile做了轻量级包装,即StoreFile底层就是HFile

2.       HLog File,HBase中WAL(Write Ahead Log) 的存储格式,物理上是Hadoop的Sequence File


(四)HBase架构及组件



Client

HBaseClient使用HBaseRPC机制与HMasterHRegionServer进行通信.

对于管理类操作,ClientHMaster进行RPC;对于数据读写类操作,ClientHRegionServer进行RPC

HBaseClient包含访问HBase的接口,并维护cache来加快对HBase的访问,比如region的位置信息


Zookeeper

HBase中有两张特殊的Table-ROOT-.META.

Ø .META.:记录了用户表的Region信息,.META.可以有多个regoin

Ø -ROOT-:记录了.META.表的Region信息,-ROOT-只有一个region

Ø Zookeeper中记录了-ROOT-表的location

(1) Client访问用户数据之前需要首先访问zookeeper,拿到-ROOT表的位置信息,然后访问-ROOT-表,拿到对应的.META表的位置信息,接着访问.META.表,最后才能找到用户数据的位置去访问,中间需要多次网络操作,不过client端会做cache缓存。

(2)ZookeeperQuorum中除了存储了-ROOT-表的地址和HMaster的地址,HRegionServer也会把自己以Ephemeral方式注册到Zookeeper中,使得HMaster可以随时感知到各个HRegionServer的健康状态。此外,Zookeeper也避免了HMaster的单点问题,见下文描述


HMaster

HMaster没有单点问题,HBase中可以启动多个HMaster,通过ZookeeperMasterElection机制保证总有一个Master运行,HMaster在功能上主要负责TableRegion的管理工作:

1.      管理用户对Table的增、删、改、查操作

2.      管理HRegionServer的负载均衡,调整Region分布

3.      RegionSplit后,负责新Region的分配

4.      HRegionServer停机后,负责失效HRegionServer上的Regions迁移


HRegionServer

HRegionServer维护region,处理对这些regionIO请求,向HDFS文件系统中读写数据,是HBase中最核心的模块。


(五)HBase和Hadoop关系

理论上HBase可以运行在任何分布式文件系统智商,只是HBase和Hadoop集成更加紧密,且与其他分布式文件系统相比,HBase投入了更多的研发努力,是的在HDFS上工作更好一些。


Region Server和HDFS的DataNode典型情况下并列配置在同一台物理硬件之上,虽说这不是必须的。

实际上唯一而的要求是Region Server能够访问到HDFS,Region Server本质上说是HDFS客户端,在其上存储/访问数据。


至于Hadoop作业如何以HBase作为数据源,作业结束时如何用HBase来接受数据,以及作业执行过程中如何用HBase来共享资源,以后介绍!

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐