hbase的服务体系遵从的是主从结构,由HRegion(服务器)-HRegionServer(服务器集群)-HMaster(主服务器)构成,
从图中能看出多个HRegion 组成一个HRegionServer,HMaster管理所有的HRegion. 所有的服务器都是通过zookeeper来进行管理和协调工作的。
HMaster并不存储hbase中的数据,hbase逻辑上的表可能会被划分成多个HRegion,存到HRegion的集群中,hbase存储的是数据到HRegion集群中的映射
HRegion
当一张表的数据超过设置的其设置的值的时候,hbase会自动将表划分成不同的区域,每一个区域包含所有行的一个子集,对于用户来说,一张表就是一个数据集,我们通过主键来区分数据。从物理上来说,一张表被分成了一个个HRegion块,我们通过表名+开始/结束 主键区分,一个HRegion会保存某一段一个表中连续数据,从开始主键到结束主键一张完整的表格式保存在多个HRegion上面的。
HRegionServer
所有的数据一般都是存在hdfs上的,用户通过HRegion来获取这些数据,一般一台机器上只运行一台HRegion服务器,而一个区段HRegion也只被一个HRegion服务器维护(一个HRegion服务器维护一个区段的HRegion,一台服务器上只有一个区段)
HRegionServer分为两大部分(HLOG和HRegion):
HLOG部分就是存储hbase的日志数据,采用先写日志的方式
HRegion里面有很多个HRegion,HRegion是存放真实数据的,HRegion里面又有很多个Store,每个Store存储的实际上是一个列族下的数据,每一个Store都有一块MemStore,
Hbase中不涉及对数据的删除更新操作,他所有的更新操作都是以追加的方式进行。数据的删除和更新操作都在数据合并的时候进行,当超过Store中StoreFile的数量时候会进行数据合并,会触发数据合并操作,会把多个StoreFile合并成一个
当用户需要更新数据的时候,hbase会把数据提交对应的HRegionServer上进行修改,数据会首先提交到log日志中,在写入log之后,才会commint()调用才会返回给客户端,如果某一台HRegionServer出现故障的时候,那么它所维护的HRegion会被分配到新的HRegionServer中,log日志会根据HRegion进行划分,当新的HRegionServer在加载HRegion时候,根据log日志对数据进行数据恢复
当一个HRegion变的巨大超过其设置的阀值后,HRegionServer会调用HRegion的closeAndSpilt(),将这个HRegion拆分成两个,并报告主服务器使用哪个HRegionServer存放新的HRegion。这个过程会很快,因为原来的两个HReegion只是保留了StoreFile文件的引用,拆分的时候HRegion会处于服务停止的状态,当新的HRegion拆分完并把引用删除后,旧的HRegion才会删除。另外,两个HRegion可以通过调用HRegion.closeAndMeger()将两个HRegion合并成一个新的HRegion(有的Hbase版本在执行此操作的时候需要两台服务器都停止服务)
HMaster
每台HRegionServer都会跟HMaster进行通信,HMaster会告诉HRegionServer要维护哪些HRegion
当一台新的HRegionServer加入到HMaster服务器时,HMaster会先告诉他等待分配数,当有HRegion死机的时候,HMaster会把它分给其他的HRegionServer
如果一个Hbase可以启动多个HMaster服务,那么可是使用zookeper来保证只有一个HMaster运行
HMaster主要职责:
1:负责用户的增删改查操作
2:管理HRegionServer的负载均衡,分配HRegion
3:在HRegion分裂后,负责分配新的HRegion
4:在HRegion失效后,对失效的HRegion进行迁移
ROOT表和META表
ROOT表(根数据表):存储的是所有HRegion的元数据信息,并且这个表的数据不能分割,只存在一个HRegion。
META表(元数据表):存的是HRegion和HRegionServer的映射关系
区分HRegion一般使用 表名+主键范围,HRegion里面存储的是连续的数据,所以一般使用主键就可以确定HRegion,但是HRegion有合并,分割的操作,有可能在进行这个操作的时候出现死机,这时就有可能出现多份相同的主键和表名的数据。这个时候使用 主键+表名就不能确定哪个HRegion了。
HRegion的区分方式最好使用 表名+主键+唯一id(regionID),这些数据就是元数据,元数据本身是存在HRegion里,META表存的是HRegion和HRegionServer的映射关系。元数据也会不停的增长,为了定位这些元数据表的位置,我们把元数据表的位置放在ROOT表中,这个表存放所有元数据表的位置,这个表是不被分割的。
Hbase在启动的时候主服务器会先扫描root表,(因为这个表只有一个 HRegion,所以HRegion的名字是写死的)将表分配 给对应的HRegion。
当root表被分配好以后,就会读取元数据表的名字和元数据表的位置,然后把元数据表(metaTable)分配给不同的HRegionServer,然后再读取元数据表,找到HRegion的区域信息,分配给不同的HRegionServer
元数据表和跟数据表的每一行都包含一个列族
所以,当客户端拿到根数据表时,就不需要再访问主服务器了。因为,root表包含所有meta表的位置,meta表包含所有用户的空间区域列表和HRegionServer的位置,客户端可以缓存已知所有的root表和meta表。主服务器就负责超时的HRegion,就只在hbase启动的时候扫描root表和meta表,以及返回root表的HRegionServer位置
zookeeper
zookeeper里存储的是root表和meta表 的位置,每台机器都会在zookeeper中注册一个实例,zookeeper就会监控这些机器的状态,当某一台机器出现故障时,zookeeper会第一个感知,然后告诉hMaster然后进行相关处理,zookeepe还负责hMaster的恢复工作,并保证在同一时刻,只有一个hMaster提供服务。