一、HBase概况介绍
HBase是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PC Server上搭建大规模结构化的存储集群。HBase的目标是存储并处理大型数据,具体来说是仅需使用普通的硬件配置,就能够处理由成千上万的行和列所组成的大型数据。
与MapReduce的离线批处理计算框架不同,HBase是一个可以随机访问的存储和检索数据平台,弥补了HDFS不能随机访问数据的缺陷,适合实时性要求不是非常高的业务场景。HBase存储的都是Byte数组,它不介意数据类型,允许动态、灵活的数据模型。
HBase的特点
· 大:一个表可以有上亿行,上百万列。
· 面向列:面向列表(簇)的存储和权限控制,列(簇)独立检索。
· 稀疏:对于为空(NULL)的列,并不占用存储空间,因此,表可以设计的非常稀疏。
· 无模式:每一行都有一个可以排序的主键和任意多的列,列可以根据需要动态增加,同一张表中不同的行可以有截然不同的列。
· 数据多版本:每个单元中的数据可以有多个版本,默认情况下,版本号自动分配,版本号就是单元格插入时的时间戳。
· 数据类型单一:HBase中的数据都是字符串,没有类型。
HBase 的应用场景
HBase 不适合所有场景。
首先,确信有足够多数据,如果有上亿或上千亿行数据,HBase 是很好的备选。如果只有上千或上百万行,则用传统的R DBMS 可能是更好的选择。因为所有数据可以在一两个节点保存,集群其他节点可能闲置。
其次,确信可以不依赖所有 RDBMS 的额外特性(例如,列数据类型、 第二索引、事务、高级查询语言等)。
第三,确信你有足够的硬件。因为 HDFS 在小于5个数据节点时,基本上体现不出它的优势。
虽然,HBase 能在单独的笔记本上运行良好,但这应仅当成是开发阶段的配置。
二、HBase体系结构
2.1 设计思路
HBase是一个分布式的数据库,使用Zookeeper管理集群,使用HDFS作为底层存储。在架构层面上由HMaster(Zookeeper选举产生的Leader)和多个HRegionServer组成,基本架构如下图所示:
在HBase的概念中,HRegionServer对应集群中的一个节点,一个HRegionServer负责管理多个HRegion,而一个HRegion代表一张表的一部分数据。在HBase中,一张表可能会需要很多个HRegion来存储数据,每个HRegion中的数据并不是杂乱无章的。HBase在管理HRegion的时候会给每个HRegion定义一个Rowkey的范围,落在特定范围内的数据将交给特定的Region,从而将负载分摊到多个节点,这样就充分利用了分布式的优点和特性。另外,HBase会自动调节Region所处的位置,如果一个HRegionServer过热,即大量的请求落在这个HRegionServer管理的HRegion上,HBase就会把HRegion移动到相对空闲的其它节点,依次保证集群环境被充分利用。
2.2基本架构
HBase由HMaster和HRegionServer组成,同样遵从主从服务器架构。HBase将逻辑上的表划分成多个数据块即HRegion,存储在HRegionServer中。HMaster负责管理所有的HRegionServer,它本身并不存储任何数据,而只是存储数据到HRegionServer的映射关系(元数据)。集群中的所有节点通过Zookeeper进行协调,并处理HBase运行期间可能遇到的各种问题。
三、 HBase数据模型
HBase是一个类似于BigTable的分布式数据库,它是一个稀疏的长期存储的(存在HDFS上)、多维度的、排序的映射表。这张表的索引是行关键字、列关键字和时间戳。HBase的数据都是字符串,没有类型。
可以将一个表想象成一个大的映射关系,通过行键、行键+时间戳或行键+列(列族:列修饰符),就可以定位特定数据。由于HBase是稀疏存储数据的,所以某些列可以是空白的。上表给出了com.cnn.www网站的数据存放逻辑视图,表中仅有一行数据,行的唯一标识为“com.cnn.www”,对这行数据的每一次逻辑修改都有一个时间戳关联对应。表中共有四列:contents:html、anchor:cnnsi.com、anchor:my.look.ca、mime:type,每一列以前缀的方式给出其所属的列族。
行键(RowKey)是数据行在表中的唯一标识,并作为检索记录的主键。在HBase中访问表中的行只有三种方式:通过某个行键访问、给定行键的范围访问、全表扫描。行键可以是任意字符串(最大长度64KB)并按照字典序进行存储。对于那些经常一起读取的行,需要对键值精心设计,以便它们能放在一起存储。
四、 HBase读写流程
下图是HRegionServer数据存储关系图。上文提到,HBase使用MemStore和StoreFile存储对表的更新。数据在更新时首先写入HLog和MemStore。MemStore中的数据是排序的,当MemStore累计到一定阈值时,就会创建一个新的MemStore,并且将老的MemStore添加到Flush队列,由单独的线程Flush到磁盘上,成为一个StoreFile。与此同时,系统会在Zookeeper中记录一个CheckPoint,表示这个时刻之前的数据变更已经持久化了。当系统出现意外时,可能导致MemStore中的数据丢失,此时使用HLog来恢复CheckPoint之后的数据。
StoreFile是只读的,一旦创建后就不可以再修改。因此Hbase的更新其实是不断追加的操作。当一个Store中的StoreFile达到一定阈值后,就会进行一次合并操作,将对同一个key的修改合并到一起,形成一个大的StoreFile。当StoreFile的大小达到一定阈值后,又会对 StoreFile进行切分操作,等分为两个StoreFile。
写操作流程
步骤1:Client通过Zookeeper的调度,向HRegionServer发出写数据请求,在HRegion中写数据。
步骤2:数据被写入HRegion的MemStore,直到MemStore达到预设阈值。
步骤3:MemStore中的数据被Flush成一个StoreFile。
步骤4:随着StoreFile文件的不断增多,当其数量增长到一定阈值后,触发Compact合并操作,将多个StoreFile合并成一个StoreFile,同时进行版本合并和数据删除。
步骤5:StoreFiles通过不断的Compact合并操作,逐步形成越来越大的StoreFile。
步骤6:单个StoreFile大小超过一定阈值后,触发Split操作,把当前HRegion Split成2个新的HRegion。父HRegion会下线,新Split出的2个子HRegion会被HMaster分配到相应的HRegionServer 上,使得原先1个HRegion的压力得以分流到2个HRegion上。
读操作流程
步骤1:client访问Zookeeper,查找-ROOT-表,获取.META.表信息。
步骤2:从.META.表查找,获取存放目标数据的HRegion信息,从而找到对应的HRegionServer。
步骤3:通过HRegionServer获取需要查找的数据。
步骤4:HRegionserver的内存分为MemStore和BlockCache两部分,MemStore主要用于写数据,BlockCache主要用于读数据。读请求先到MemStore中查数据,查不到就到BlockCache中查,再查不到就会到StoreFile上读,并把读的结果放入BlockCache。
hbase工作原理
Client
首先当一个请求产生时,HBase Client使用RPC(远程过程调用)机制与HMaster和HRegionServer进行通信,对于管理类操作,Client与HMaster进行RPC;对于数据读写操作,Client与HRegionServer进行RPC。
Zookeeper
HBase Client使用RPC(远程过程调用)机制与HMaster和HRegionServer进行通信,但如何寻址呢?由于Zookeeper中存储了-ROOT-表的地址和HMaster的地址,所以需要先到Zookeeper上进行寻址。
HRegionServer也会把自己以Ephemeral方式注册到Zookeeper中,使HMaster可以随时感知到各个HRegionServer的健康状态。此外,Zookeeper也避免了HMaster的单点故障。
HMaster
当用户需要进行Table和Region的管理工作时,就需要和HMaster进行通信。HBase中可以启动多个HMaster,通过Zookeeper的Master Eletion机制保证总有一个Master运行。
· 管理用户对Table的增删改查操作
· 管理HRegionServer的负载均衡,调整Region的分布
· 在Region Split后,负责新Region的分配
· 在HRegionServer停机后,负责失效HRegionServer上的Regions迁移
HRegionServer
当用户需要对数据进行读写操作时,需要访问HRegionServer。HRegionServer存取一个子表时,会创建一个HRegion对象,然后对表的每个列族创建一个Store实例,每个Store都会有一个 MemStore和0个或多个StoreFile与之对应,每个StoreFile都会对应一个HFile, HFile就是实际的存储文件。因此,一个HRegion有多少个列族就有多少个Store。 一个HRegionServer会有多个HRegion和一个HLog。
当HStore存储是HBase的核心了,其中由两部分组成:MemStore和StoreFiles。 MemStore是Sorted Memory Buffer,用户
写入数据首先 会放在MemStore,当MemStore满了以后会Flush成一个 StoreFile(实际存储在HDHS上的是HFile),当StoreFile文件数量增长到一定阀值,就会触发Compact合并操作,并将多个StoreFile合并成一个StoreFile,合并过程中会进行版本合并和数据删除,因此可以看出HBase其实只有增加数据,所有的更新和删除操作都是在后续的compact过程中进行的,这使得用户的 读写操作只要进入内存中就可以立即返回,保证了HBase I/O的高性能。
下面以一个具体数据Put的流程,让我们加深对HBase工作流程的认识。
HBase Put流程
下面是put流程的时序图:
客户端:
· 客户端发起Put写请求,讲put写入writeBuffer,如果是批量提交,写满缓存后自动提交
· 根据rowkey将put吩咐给不同regionserver
服务端:
· RegionServer将put按rowkey分给不同的region
· Region首先把数据写入wal
· wal写入成功后,把数据写入memstore
· Memstore写完后,检查memstore大小是否达到flush阀值
· 如果达到flush阀值,将memstore写入HDFS,生成HFile文件
HBase Compact &&Split
当StoreFile文件数量增长到一定阀值,就会触发Compact合并操作,并将多个StoreFile合并成一个StoreFile,当这个StoreFile大小超过一定阀值后,会触发Split操作,同时把当前Region Split成2个Region,这是旧的Region会下线,新Split出的2个Region会被HMaster分配到相应的HregionServer上,使得原先1个Region的压力得以分散到2个Region上。
如下图四个Storefile文件(从memstore文件经过flush而得到,默认64M的storefile文件)经过Compact合并成一个大的256M storefile文件,当设定的Region阀值为128M时,就会Split为两个128M的Storefile文件,然后HMaster再把这两个storefile文件分配到不停地Regionserver上。
HFile
HBase中所有的数据文件都存储在Hadoop HDFS上,主要包括两种文件类型:
· Hfile:HBase中KeyValue数据的存储格式,HFile是Hadoop的 二进制格式文件,实际上StoreFile就是对Hfile做了轻量级包装,即StoreFile底层就是HFile
· HLog File:HBase中WAL(write ahead log)的存储格式,物理上是Hadoop的Sequence File
HFile的存储格式如下:
HFile文件是不定长的,长度固定的只有其中的两块:Trailer和FileInfo。
Trailer中有指针指向其他数据块的起始点,FileInfo记录了文件的一些meta信息。 Data Block是hbase io的基本单元,为了提高效率,HRegionServer中有基于LRU的block cache机制。
每个Data块的大小可以在创建一个Table的时候通过参数指定(默认块大小64KB),大号的Block有利于顺序Scan,小号的 Block利于随机查询。
每个Data块除了开头的Magic以外就是一个个KeyValue对拼接而成,Magic内容就是一些随机数字,目的是防止数 据损坏,结构如下。
上图可知,开始是两个固定长度的数值,分别表示key的长度和alue的长度。紧接着是Key,开始是固定长度的数值,表示RowKey的长度,紧接着是RowKey,然后是固定长度的数值,表示Family的长度,然后是Family,接着是Qualifier,然后是两个固定长度的数值,表示Time Stamp和Key Type(Put/Delete)。Value部分没有那么复杂的结构,就是纯粹的二进制数据。
HBase的三维有序(即字典顺序)存储
Hfile是HBase中KeyValue数据的存储格式。从上面的 HBase物理数据模型中可以看出,HBase是面向列表(簇)的存储。每个Cell由 {row key,column(=《 family》 + 《 label》),version} 唯一确定的单元,他们组合在一起就是一个KeyValue。根据上述描述,这个KeyValue中的key就是{row key,column(=《 family》 + 《 label》),version} ,而value就是cell中的值。
HBase的三维有序存储中的三维是指:rowkey(行主键),column key(columnFamily+《 label》),timestamp(时间戳或者版本号)三部分组成的三维有序存储。
· rowkey
rowkey是行的主键,它是以字典顺序排序的。所以 rowkey的设计是至关重要的,关系到你应用层的查询效率。我们在根据rowkey范围查询的时候,我们一般是知道startRowkey,如果我们通过scan只传startRowKey : d开头的,那么查询的是所有比d大的都查了,而我们只需要d开头的数据,那就要通过endRowKey来限制。我们可以通过设定endRowKey为:d 开头,后面的根据你的rowkey组合来设定,一般是加比startKey大一位。
· column key
column key是第二维,数据按rowkey字典排序后,如果rowkey相同,则是根据column key来排序的,也是按字典排序。
我们在设计table的时候要学会利用这一点。比如我们的收件箱。我们有时候需要按主题排序,那我们就可以把主题这设置为我们的column key,即设计为columnFamily+主题。,这样的设计。
· timestamp
timestamp 时间戳,是第三维,这是个按降序排序的,即最新的数据排在最前面。这个就没有什么说的了。网上其他的博客也提到比较多。
HLog Replay
根据以上的叙述,我们已经了解了关于HStore的基本原理,但我们还必须要了解一下HLog的功能,因为上述的HStore在系统正常工作的前提下是没问题的,但是在分布式 系统环境中,无法避免系统出错或者宕机,因为一旦HRegionServer意外退出,MemStore中的内存数据将会丢失,这就需要引入HLog。每个HRegionServer中都有一个HLog对象,HLog是一个实现Write Ahead Log的类,在每一次用户操作写入MemStore的同时,也会写一份数据到HLog文件中,HLog文件定期(当文件已持久化到StoreFile中的数据)会滚出新的,并且删除旧的文件。当HRegionServer意外终止 后,HMaster会通过Zookeeper感知到,HMaster首先会处理遗留的Hlog文件,将其中不同Region的Log数据进行拆分,分别放到相应Region的目录下,然后再将失效的Region重新分配,领取到这些Region的Regionserver在Load Region的过程中,会发现历史HLog需要处理,因此Replay HLog中的数据到MemStore中,然后flush到StoreFiles,完成数据恢复。
HLog存储格式
WAL(Write Ahead Log):RegionServer在处理插入和删除过程中,用来记录操作内容的日志,只有日志写入成功,才会通知客户端操作成功。
上图中是HLog文件的结构,其实HLog文件就是一个普通的Hadoop Sequence File,Sequence File的Key是HLogKey对象,HLogKey中记录了写入数据的归属信息,除了table和Region名字外,同时还包括sequence number和timestamp,timestamp是”写入时间”,sequence number 的起始值为0,或者是最近一次存入文件系统中的sequence number。
HLog Sequence File 的Value是HBase的KeyValue对象昂,即对应HFile中的KeyValue。
HBase性能和优化影响HBase性能的因素
评论
查看更多