HBase 原理

来源:互联网 发布:淘宝商家开通花呗 编辑:程序博客网 时间:2024/05/17 06:23

概述

hbase是建立的hdfs之上,提供高可靠性、高性能、列存储、可伸缩、实时读写的数据库系统。

HBase中的表一般有这样的特点

1、大:一个表可以有上亿行,上百万列

2、面向列:面向列(族)的存储和权限控制,列(族)独立检索。

3、稀疏:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏。



物理存储

1. Table中的所有行都按照row key的字典序排列。
2. Table 在行的方向上分割为多个Hregion。
这里写图片描述

3. region按大小分割的,每个表一开始只有一个region,随着数据不断插入表,region不断增大,当增大到一个阀值(默认256M)的时候,Hregion就会等分会两个新的Hregion。当table中的行不断增多,就会有越来越多的Hregion。
这里写图片描述

4. Hregion是Hbase中分布式存储和负载均衡的最小单元。最小单元就表示不同的Hregion可以分布在不同的HRegion server上。但一个Hregion是不会拆分到多个server上的。
这里写图片描述

5. HRegion虽然是分布式存储的最小单元,但并不是存储的最小单元。
事实上,HRegion由一个或者多个Store组成,每个store保存一个columns family。
每个Strore又由一个memStore和0至多个StoreFile组成。StoreFile以HFile格式保存在HDFS上。
这里写图片描述




架构图

这里写图片描述

Client

HBASE Client使用HBASE的RPC机制与HMaster和RegionServer进行通信
管 理 类 操 作    :Client与HMaster进行RPC;
数据读写类操作:Client与HRegionServer进行RPC。

Zookeeper

1、保证任何时候,集群中只有一个master

2、存贮所有Region的寻址入口。

3、实时监控Region Server的状态,将Region server的上线和下线信息实时通知给Master

4、存储Hbase的schema,包括有哪些table,每个table有哪些column family

HMaster

1、为Region server分配region (Region server切分好region之后,master进行分配到其他机器)

2、负责region server的负载均衡(region分配、新机器加入时管理HRegion Server的负载均衡并调整Region分布)

3、在HRegion Server宕机后,负责失效HRegion Server 上的Regions迁移。

4、GFS上的垃圾文件回收(hdfs)

5、处理schema更新请求 (DDL:创建表/删除表/修改表)

HRegionServer

1、 Region server维护Master分配给它的region,处理对这些region的IO请求

2、 Region server负责切分在运行过程中变得过大的region

可以看到,client访问hbase上的数据并不需要master参与(寻址访问zookeeper和region server,数据读写访问region server),master仅仅维护table和region的元数据信息(table的元数据信息保存在zookeeper上),负载很低。 HRegionServer存取一个子表时,会创建一个HRegion对象,然后对表的每个列族创建一个Store实例,每个Store都会有一个MemStore和0个或多个StoreFile与之对应,每个StoreFile都会对应一个HFile, HFile就是实际的存储文件。因此,一个HRegion有多少个列族就有多少个Store。 一个HRegionServer会有多个HRegion和一个HLog。

HRegion

      table在行的方向上分隔为多个Region。Region是HBase中分布式存储和负载均衡的最小单元,即不同的region可以分别在不同的Region Server上,但同一个Region是不会拆分到多个server上。

      Region按大小分隔,每个表一般是只有一个region。随着数据不断插入表,region不断增大,当region的某个列族达到一个阈值(默认256M)时就会分成两个新的region。

每个region由以下信息标识:
    1、< 表名,startRowkey,创建时间>
    2、由目录表(-ROOT-和.META.)记录该region的endRowkey

HRegion定位

Region被分配给哪个Region Server是完全动态的,所以需要机制来定位Region具体在哪个region server。

HBase使用三层结构来定位region

步骤:
1、Client通过访问ZK来请求目标数据的地址。

2、ZK中保存了-ROOT-表的地址,所以ZK通过访问-ROOT-表来请求数据地址。

3、同样,-ROOT-表中保存的是.META.的信息,通过访问.META.表来获取具体的RS。

4、.META.表查询到具体RS信息后返回具体RS地址给Client。

5、Client端获取到目标地址后,然后直接向该地址发送数据请求。
这里写图片描述

说明
1、 root region永远不会被split,保证了最需要三次跳转,就能定位到任意region 。

2、META.表每行保存一个region的位置信息,row key 采用表名+表的最后一样编码而成。

3、为了加快访问,.META.表的全部region都保存在内存中。
假设,.META.表的一行在内存中大约占用1KB。并且每个region限制为128MB。
那么上面的三层结构可以保存的region数目为:
(128MB/1KB) * (128MB/1KB) = = 2(34)个region

4、client会将查询过的位置信息保存缓存起来,缓存不会主动失效,因此如果client上的缓存全部失效,则需要进行6次网络来回,才能定位到正确的region(其中三次用来发现缓存失效,另外三次用来获取位置信息)。

说明:
    -ROOT-表:表包含.META.表所在的region列表,该表只有一个Region;Zookeeper中记录了-ROOT-表的location

    .META.表:表包含所有的用户空间region列表,以及Region Server的服务器地址

Store

      每一个region由一个或多个store组成,至少是一个store,hbase会把一起访问的数据放在一个store里面,即为每个ColumnFamily建一个store,如果有几个ColumnFamily,也就有几个Store。一个Store由一个memStore和0或者多个StoreFile组成。 HBase以store的大小来判断是否需要切分region。

MemStore

      memStore 是放在内存里的。保存修改的数据即keyValues。当memStore的大小达到一个阀值(默认64MB)时,memStore会被flush到文件,即生成一个快照。目前hbase 会有一个线程来负责memStore的flush操作。

StoreFile

memStore内存中的数据写到文件后就是StoreFile,StoreFile底层是以HFile的格式保存。

HLog

       其实HLog文件就是一个普通的Hadoop Sequence File, Sequence File的value是key时HLogKey对象,其中记录了写入数据的归属信息,除了table和region名字外,还同时包括sequence number和timestamp,timestamp是写入时间,sequence number的起始值为0,或者是最近一次存入文件系统中的sequence number。 Sequence File的value是HBase的KeyValue对象,即对应HFile中的KeyValue。

       HLog(WAL log):WAL意为write ahead log,用来做灾难恢复使用,HLog记录数据的所有变更,一旦region server 宕机,就可以从log中进行恢复。

LogFlusher

       数据以KeyValue形式到达HRegionServer,将写入WAL之后,写入一个SequenceFile。看过去没问题,但是因为数据流在写入文件系统时,经常会缓存以提高性能。这样,有些本以为在日志文件中的数据实际在内存中。这里,我们提供了一个LogFlusher的类。它调用HLog.optionalSync(),后者根据 hbase.regionserver.optionallogflushinterval (默认是10秒),定期调用Hlog.sync()。另外,HLog.doWrite()也会根据 hbase.regionserver.flushlogentries (默认100秒)定期调用Hlog.sync()。Sync() 本身调用HLog.Writer.sync(),它由SequenceFileLogWriter实现。

LogRoller

       Log的大小通过$HBASE_HOME/conf/hbase-site.xml 的 hbase.regionserver.logroll.period 限制,默认是一个小时。所以每60分钟,会打开一个新的log文件。久而久之,会有一大堆的文件需要维护。首先,LogRoller调用HLog.rollWriter(),定时滚动日志,之后,利用HLog.cleanOldLogs()可以清除旧的日志。它首先取得存储文件中的最大的sequence number,之后检查是否存在一个log所有的条目的“sequence number”均低于这个值,如果存在,将删除这个log。 每个region server维护一个HLog,而不是每一个region一个,这样不同region(来自不同的table)的日志会混在一起,这样做的目的是不断追加单个文件相对于同时写多个文件而言,可以减少磁盘寻址次数,因此可以提高table的写性能。带来麻烦的时,如果一个region server下线,为了恢复其上的region,需要将region server上的log进行拆分,然后分发到其他region server上进行恢复。




流程

这里写图片描述

简要说明

按照启动顺序:zk、hmaster、hregionServer。当regionServer都启动起来之后并向zk通过RPC发送心跳汇报信息,同时hmaster也会向zk汇报信息,这时master即可间接获取regionServer的信息。若hmaster宕机zk会将Backup Masters切换为active master。

client要读写数据,首先连接zk,从zk缓存中获取数据之后直接跟regionServe直连来进行读写数据。

client进行DDL操作,首先跟master交互,然后master再跟regionServer进行打交道

写流程

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上

数据flush过程

1、当memstore数据达到阈值(默认是64M),将数据刷到硬盘,将内存中的数据删除,同时删除Hlog中的历史数据。
2、并将数据存储到hdfs中。
3、在hlog中做标记点。

数据合并过程

1、当数据块达到4块,hmaster将数据块加载到本地,进行合并
2、当合并的数据超过256M,进行拆分,将拆分后的region分配给不同的hregionserver管理
3、当hregionser宕机后,将hregionserver上的hlog拆分,然后分配给不同的hregionserver加载,修改.META.
4、注意:hlog会同步到hdfs

hbase的读流程

1、client访问Zookeeper,查找-ROOT-表,获取.META.表信息。

2、从.META.表查找,获取存放目标数据的HRegion信息,从而找到对应的HRegionServer。

3、通过HRegionServer获取需要查找的数据。

4、HRegionserver的内存分为MemStore和BlockCache两部分,MemStore主要用于写数据,BlockCache主要用于读数据。读请求先到MemStore中查数据,查不到就到BlockCache中查,再查不到就会到StoreFile上读,并把读的结果放入BlockCache。(由于client连接到zk的,当数据发生变化,regionServer会向zk汇报信息,然后缓存更新)

0 0
原创粉丝点击