**注:**一张hbase表在刚刚创建的时候,默认只有一个region。所以多有关于这张表的请求都被路由到同一个region server,不管集群中有多少region server。这也就是为什么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存储由两部分组成:MemStore和StoreFiles。 MemStore是Sorted Memory Buffer,用户 写入数据首先 会放在MemStore,当MemStore满了以后会Flush成一个 StoreFile(实际存储在HDHS上的是HFile),当StoreFile文件数量增长到一定阀值,就会触发Compact合并操作,并将多个StoreFile合并成一个StoreFile,合并过程中会进行版本合并和数据删除,因此可以看出HBase其实只有增加数据,所有的更新和删除操作都是在后续的compact过程中进行的,这使得用户的 读写操作*只要进入内存中就可以立即返回,保证了HBase I/O的高性能。
HBase的用-ROOT-表来记录.META.的Region信息,就和.META.记录用户表的Region信息一模一样。-ROOT-只会有一个Region。
这么一来Client端就需要先去访问-ROOT-表。所以需要知道管理-ROOT-表的RegionServer的地址。这个地址被存在ZooKeeper中。默认的路径是: /hbase/root-region-server
-ROOT-行记录结构
.META.表结构
HBase的所有Region元数据被存储在.META.表中,随着Region的增多,.META.表中的数据也会增大,并分裂成多个新的Region。为了定位.META.表中各个Region的位置,把.META.表中所有Region的元数据保存在-ROOT-表中,最后由Zookeeper记录-ROOT-表的位置信息。所有客户端访问用户数据前,需要首先访问Zookeeper获得-ROOT-的位置,然后访问-ROOT-表获得.META.表的位置,最后根据.META.表中的信息确定用户数据存放的位置,如下图所示。
-ROOT-表永远不会被分割,它只有一个Region,这样可以保证最多只需要三次跳转就可以定位任意一个Region。为了加快访问速度,.META.表的所有Region全部保存在内存中。客户端会将查询过的位置信息缓存起来,且缓存不会主动失效。如果客户端根据缓存信息还访问不到数据,则询问相关.META.表的Region服务器,试图获取数据的位置,如果还是失败,则询问-ROOT-表相关的.META.表在哪里。最后,如果前面的信息全部失效,则通过ZooKeeper重新定位Region的信息。所以如果客户端上的缓存全部是失效,则需要进行6次网络来回,才能定位到正确的Region。
最后要提醒大家注意两件事情:
参考:
http://www.javashuo.com/article/p-pmaokxal-hh.html
https://blog.csdn.net/ldds_520/article/details/51674315
http://www.javashuo.com/article/p-qmoiefxq-hs.html
参考:https://blog.csdn.net/jiangmingzhi23/article/details/78609864
写请求被region server处理,region server会先将数据写到称为“memstore”的内存存储系统中。一旦memstore写满,就会被写到磁盘上的存储文件中,这个过程称为“memstore flush”。随着存储文件的积累,region server会将它们合并成一个更大文件。随着每一次写磁盘和合并操作完成,如果region拆分策略任务这个region需要被拆分,则会发起region拆分请求。由于hbase所有的数据文件是不可变的,进行region拆分时,一个region被拆分为两个region时,两个新创建的region不会重写所有的数据到新的文件,而是创建小的sym-link文件,sym-link文件也叫reference文件。reference文件根据分割点,指向父存储文件的顶部或底部。reference文件的使用和常规数据文件一样,但它只有一半的记录。如果reference文件不再有对父region的不可变数据文件的引用,则这个region不可以再拆分。这些reference文件通过合并逐渐清理,以便该region停止引用其父文件,并可以进一步拆分。
尽管region拆分是由region server本地进行决策的,但是拆分过程却有很多参与者。region server在region拆分前后都会通知Master进程更新.META.表, 以便client可以找到拆分出来的新的两个region。还需要重新排列目录结构以及HDFS中的数据文件。region拆分过程有多个任务完成。为了在发生错误时可以回滚,regionserver会在内存中保存执行状态日志。图1显示了Region Server执行拆分的步骤。每个步骤都标有其步骤编号。来自Region Servers或Master的操作显示为红色,而来自客户端的操作显示为绿色。
/hbase/.tmp
:临时目录,当对表做创建和删除的时候,会将表move到该目录,然后进行操作/hbase/data
:核心目录,存储HBase表的数据 默认情况下,目录下有两个目录/hbase/data/default
: 在用户创建表的时候,没有指定namespace时,表就创建在此目录下/hbase/data/hbase
:系统内部创建的表,.META.表(region的详细信息)和namespace表(namespace信息)/hbase/hbase.id
:存储的是集群的唯一cluster id(uuid)/hbase/hbase.version
:集群的版本号/hbase/oldWALs
: 对应0.94.x版本中.oldlogs目录 当/hbase/WALs目录中的logs没有之后,会将这些logs移动到此目录下,HMaster会定期清理参考:
http://dxer.github.io/2016/03/19/hbase%E7%AE%80%E4%BB%8B/
(1) Client通过Zookeeper的调度,向RegionServer发出写数据请求,在Region中写数据。
(2) 数据被写入Region的MemStore,直到MemStore达到预设阈值。
(3) MemStore中的数据被Flush成一个StoreFile。
(4) 随着StoreFile文件的不断增多,当其数量增长到一定阈值后,触发Compact合并操作,将多个StoreFile合并成一个StoreFile,同时进行版本合并和数据删除。
(5) StoreFiles通过不断的Compact合并操作,逐步形成越来越大的StoreFile。
(6) 单个StoreFile大小超过一定阈值后,触发Split操作,把当前Region Split成2个新的Region。父Region会下线,新Split出的2个子Region会被HMaster分配到相应的RegionServer上,使得原先1个Region的压力得以分流到2个Region上。
可以看出HBase只有增添数据,所有的更新和删除操作都是在后续的Compact历程中举行的,使得用户的写操作只要进入内存就可以立刻返回,实现了HBase I/O的高性能。
(1) Client访问Zookeeper,查找-ROOT-表,获取.META.表信息。
(2) 从.META.表查找,获取存放目标数据的Region信息,从而找到对应的RegionServer。
(3) 通过RegionServer获取需要查找的数据。
(4) Regionserver的内存分为MemStore和BlockCache两部分,MemStore主要用于写数据,BlockCache主要用于读数据。读请求先到MemStore中查数据,查不到就到BlockCache中查,再查不到就会到StoreFile上读,并把读的结果放入BlockCache。
寻址过程:client–>Zookeeper–>-ROOT-表–>META表–>RegionServer–>Region–>client