@Author : Spinach | GHB
@Link :
文章目录
- HBase架构图
- -ROOT-和.META.结构
- -ROOT-
- .META.
- 两表关系(hbase0.96版本之前,之后删除了-ROOT-表)
- 写数据过程
- 读数据过程
- HBase各个模块功能
HBase架构图
-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-表。
除了没有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
.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.表中的信息确定用户数据存放的位置,
-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只有增添数据,所有的更新和删除操作都是在后续的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上。
读数据过程
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的元数据信息,负载很低。