@Author  : Spinach | GHB
@Link    :

文章目录

  • HBase架构图
  • -ROOT-和.META.结构
  • -ROOT-
  • .META.
  • 两表关系(hbase0.96版本之前,之后删除了-ROOT-表)
  • 写数据过程
  • 读数据过程
  • HBase各个模块功能


HBase架构图

hbase写入最大速率 hbase读写性能对比_Hbase读写数据过程详解


hbase写入最大速率 hbase读写性能对比_hbase写入最大速率_02

-ROOT-和.META.结构

从存储结构和操作方法的角度来说,-ROOT-、.META.与其他表没有任何区别。它们与众不同的地方是HBase用它们来存贮一个重要的系统信息:

  • -ROOT-:记录.META.表的Region信息。
  • .META.:记录用户表的Region信息。

其中-ROOT-表本身只会有一个region,也就只会存放在一台RegionServer上。,这样保证了只需要三次跳转,就能定位到任意region。

hbase0.96版本之前

-ROOT-和.META.均存储在HBase中,可通过以下命令查看scan '-ROOT-'和scan ‘.META.’,存放-ROOT-的所处region的地址放在zookeeper中,路径为/hbase/root-region-server。

hbase0.96版本之后

.META.存储在HBase中,可通过以下命令查看scan ‘hbase:meta’,存放.META.的所处region的地址放在zookeeper中,路径为/hbase/meta-region-server。

-ROOT-

hbase0.96版本后删除了root表,新增了namespace,现在是讲解hbase0.96版本之前的版本。

当用户表特别大时,用户表的region也会非常多。.META.表存储了这些region信息,也变得非常大,这时.META.自己也需要划分成多个Region,托管到多个RegionServer上。这时就出现了一个问题:当.META.被托管在多个RegionServer上,如何去定位.META.呢?HBase的做法是用另外一个表来记录.META.的Region信息,就和.META.记录用户表的Region信息一样,这个表就是-ROOT-表。

hbase写入最大速率 hbase读写性能对比_Hbase读写数据过程详解_03

除了没有historian列族之外,-ROOT-表的结构与.META.表的结构是一样的。另外,-ROOT-表的 RowKey 没有采用时间戳,也没有Encoded值,而是直接指定一个数字。

.META.
hbase(main):018:0> scan 'hbase:meta'
ROW                                                               COLUMN+CELL  
 CallLog,,1528959142280.21bd88f3409aed49228d3b9dd9f8d7c0.         column=info:regioninfo, timestamp=1538750384211, value={ENCODED => 21bd88f3409aed49228d3b9dd9f8d7c0, NAME => 'CallLog,,1528959142280.21bd88f3409aed49228d3b9dd9f8d7c0.', STARTKEY => '', ENDKE
                                                                  Y => ''}     
 CallLog,,1528959142280.21bd88f3409aed49228d3b9dd9f8d7c0.         column=info:seqnumDuringOpen, timestamp=1538750384211, value=\x00\x00\x00\x00\x00\x00\x00(                                           
 CallLog,,1528959142280.21bd88f3409aed49228d3b9dd9f8d7c0.         column=info:server, timestamp=1538750384211, value=centos6:16201              
 CallLog,,1528959142280.21bd88f3409aed49228d3b9dd9f8d7c0.         column=info:serverstartcode, timestamp=1538750384211, value=1538750349345     
 hbase:namespace,,1528879579816.45aa5ea87654b8e16223ca82c351473f. column=info:regioninfo, timestamp=1538750384222, value={ENCODED => 45aa5ea87654b8e16223ca82c351473f, NAME => 'hbase:namespace,,1528879579816.45aa5ea87654b8e16223ca82c351473f.', STARTKEY => '
                                                                  ', ENDKEY => ''}                                     
 hbase:namespace,,1528879579816.45aa5ea87654b8e16223ca82c351473f. column=info:seqnumDuringOpen, timestamp=1538750384222, value=\x00\x00\x00\x00\x00\x00\x00=                                           
 hbase:namespace,,1528879579816.45aa5ea87654b8e16223ca82c351473f. column=info:server, timestamp=1538750384222, value=centos6:16201              
 hbase:namespace,,1528879579816.45aa5ea87654b8e16223ca82c351473f. column=info:serverstartcode, timestamp=1538750384222, value=1538750349345     
 ns1:calllogs,,1532873264166.bd62c4d5567f7d1533cb48fa517d9721.    column=info:regioninfo, timestamp=1538750384217, value={ENCODED => bd62c4d5567f7d1533cb48fa517d9721, NAME => 'ns1:calllogs,,1532873264166.bd62c4d5567f7d1533cb48fa517d9721.', STARTKEY => '', 
                                                                  ENDKEY => ''}
 ns1:calllogs,,1532873264166.bd62c4d5567f7d1533cb48fa517d9721.    column=info:seqnumDuringOpen, timestamp=1538750384217, value=\x00\x00\x00\x00\x00\x00\x00\x0C                                        
 ns1:calllogs,,1532873264166.bd62c4d5567f7d1533cb48fa517d9721.    column=info:server, timestamp=1538750384217, value=centos6:16201              
 ns1:calllogs,,1532873264166.bd62c4d5567f7d1533cb48fa517d9721.    column=info:serverstartcode, timestamp=1538750384217, value=1538750349345     3 row(s) in 0.0200 seconds


hbase(main):020:0> desc 'hbase:meta'
Table hbase:meta is ENABLED                                                    
hbase:meta, {TABLE_ATTRIBUTES => {IS_META => 'true', REGION_REPLICATION => '1', coprocessor$1 => '|org.apache.hadoop.hbase.coprocessor.MultiRowMutationEndpoint|536870911|'}                                                                  
COLUMN FAMILIES DESCRIPTION                                                 
{NAME => 'info', BLOOMFILTER => 'NONE', VERSIONS => '10', IN_MEMORY => 'true', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', CACHE_DATA_IN_L1 => 'true', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLO
CKSIZE => '8192', REPLICATION_SCOPE => '0'}                                    
1 row(s) in 0.0210 seconds

hbase写入最大速率 hbase读写性能对比_读写数据过程_04

.META.表中每一行记录了一个Region的信息。

结构说明

  • rowkey

RowKey就是Region Name,它的命名形式是TableName,StartKey,TimeStamp.Encoded.。
第一个region的startKey是空字符串;

CallLog,,1528959142280.21bd88f3409aed49228d3b9dd9f8d7c0.

其中 Encoded 是TableName,StartKey,TimeStamp的md5值。

  • Column Family

.META.表有两个Column Family:info和historian。其中info包含了三个Column:

1. regioninfo:region的详细信息,包括StartKey、EndKey以及Table信息等等。
   a. startKey,region的开始key,第一个region的startKey是空字符串;
   b. endKey,region的结束key,最后一个region的endKey是空字符串;
2. server:管理该region的 RegionServer 的地址。
3. serverstartcode:RegionServer 开始托管该region的时间。
两表关系(hbase0.96版本之前,之后删除了-ROOT-表)

hbase0.96版本后删除了root表,新增了namespace,现在是讲解hbase0.96版本之前的版本。

HBase的所有Region元数据被存储在.META.表中2.1,随着Region的增多,.META.表中的数据也会增大,并分裂成多个新的Region。为了定位.META.表中各个Region的位置,把.META.表中所有Region的元数据保存在-ROOT-表中,最后由Zookeeper记录-ROOT-表的位置信息。所有客户端访问用户数据前,需要首先访问Zookeeper获得-ROOT-的位置,然后访问-ROOT-表获得.META.表的位置,最后根据.META.表中的信息确定用户数据存放的位置,

hbase写入最大速率 hbase读写性能对比_hbase写入最大速率_05

-ROOT-表永远不会被分割,它只有一个Region,也就只会存放在一台RegionServer上。这样可以保证最多只需要三次跳转就可以定位任意一个Region。为了加快访问速度,.META.表的所有Region全部保存在内存中。客户端会将查询过的位置信息缓存起来,且缓存不会主动失效。如果客户端根据缓存信息还访问不到数据,则询问相关.META.表的Region服务器,试图获取数据的位置,如果还是失败,则询问-ROOT-表相关的.META.表在哪里。最后,如果前面的信息全部失效,则通过ZooKeeper重新定位Region的信息。所以如果客户端上的缓存全部是失效,则需要进行6次网络来回,才能定位到正确的Region。

写数据过程

hbase0.96版本之前

  • Client通过Zookeeper的调度,向RegionServer发出写数据请求,zk存储了-ROOT-表(记录.META.表的Region信息),从-ROOT-表中找到.META.表(记录用户表的Region信息)。
  • 根据namespace、表名和rowkey根据meta表的数据找到写入数据对应的region信息找到对应的regionserver;
  • 把数据被写入Region的MemStore,并写到HLog中,直到MemStore达到预设阈值,MemStore中的数据被Flush成一个StoreFile。
  • 随着StoreFile文件的不断增多,当其数量增长到一定阈值后,触发Compact合并操作,将多个StoreFile合并成一个StoreFile,同时进行版本合并和数据删除。
  • StoreFiles通过不断的Compact合并操作,逐步形成越来越大的StoreFile。
  • 单个StoreFile大小超过一定阈值后,触发Split操作,把当前Region Split成2个新的Region。父Region会下线,新Split出的2个子Region会被HMaster分配到相应的RegionServer上,使得原先1个Region的压力得以分流到2个Region上。

hbase写入最大速率 hbase读写性能对比_读写数据过程_06

可以看出HBase只有增添数据,所有的更新和删除操作都是在后续的Compact历程中举行的,使得用户的写操作只要进入内存就可以立刻返回,实现了HBase I/O的高性能。

hbase0.96版本之后,新增了namespace

  • zookeeper中存储了meta表的region信息,从meta表获取相应region信息,然后找到meta表的数据;
  • 根据namespace、表名和rowkey根据meta表的数据找到写入数据对应的region信息找到对应的regionserver;
  • 把数据被写入Region的MemStore,并写到HLog中,直到MemStore达到预设阈值,MemStore中的数据被Flush成一个StoreFile。
  • 随着StoreFile文件的不断增多,当其数量增长到一定阈值后,触发Compact合并操作,将多个StoreFile合并成一个StoreFile,同时进行版本合并和数据删除。
  • StoreFiles通过不断的Compact合并操作,逐步形成越来越大的StoreFile。
  • 单个StoreFile大小超过一定阈值后,触发Split操作,把当前Region Split成2个新的Region。父Region会下线,新Split出的2个子Region会被HMaster分配到相应的RegionServer上,使得原先1个Region的压力得以分流到2个Region上。

hbase写入最大速率 hbase读写性能对比_hbase写入最大速率_07

读数据过程

hbase0.96版本之前

  • Client访问Zookeeper,查找-ROOT-表,获取.META.表信息。
  • 从.META.表查找,获取存放目标数据的Region信息,从而找到对应的RegionServer。
  • 通过RegionServer获取需要查找的数据。
  • Regionserver的内存分为MemStore和BlockCache两部分,MemStore主要用于写数据,BlockCache主要用于读数据。读请求先到MemStore中查数据,查不到就到BlockCache中查,再查不到就会到StoreFile上读,并把读的结果放入BlockCache。

寻址过程:client–>Zookeeper–>-ROOT-表–>META表–>RegionServer–>Region–>client

hbase0.96版本之后,新增了namespace

  • zookeeper中存储了meta表的region信息,所以先从zookeeper中找到meta表region的位置,然后读取meta表中的数据。meta中又存储了用户表的region信息;
  • 根据namespace、表名和rowkey在meta表中找到对应的region信息;
  • 找到这个region对应的regionserver
  • 查找对应的region;
  • 先从MemStore找数据,如果没有,再到StoreFile上读(为了读取的效率)。

寻址过程:client–>Zookeeper–>META表–>RegionServer–>Region–>client

HBase各个模块功能

Client

  • 整个HBase集群的访问入口;
  • 使用HBase RPC机制与HMaster和HRegionServer进行通信;
  • 与HMaster进行通信进行管理表的操作;
  • 与HRegionServer进行数据读写类操作;
  • 包含访问HBase的接口,并维护cache来加快对HBase的访问

Zookeeper

  • 保证任何时候,集群中只有一个HMaster;
  • 存贮所有HRegion的寻址入口;
  • 实时监控HRegion Server的上线和下线信息,并实时通知给HMaster;
  • 存储HBase的schema和table元数据;
  • Zookeeper Quorum存储表地址、HMaster地址。

HMaster

  • HMaster没有单点问题,HBase中可以启动多个HMaster,通过Zookeeper的Master Election机制保证总有一个Master在运行,主负责Table和Region的管理工作。
  • 管理用户对表的创建、删除等操作;
  • 管理HRegionServer的负载均衡,调整Region分布;
  • Region Split后,负责新Region的分布;
  • 在HRegionServer停机后,负责失效HRegionServer上Region迁移工作。

HRegion Server

  • 维护HRegion,处理对这些HRegion的IO请求,向HDFS文件系统中读写数据;
  • 负责切分在运行过程中变得过大的HRegion。
  • Client访问hbase上数据的过程并不需要master参与(寻址访问Zookeeper和HRegion Server,数据读写访问HRegione Server),HMaster仅仅维护这table和Region的元数据信息,负载很低。