HBase的zookeeper中保存HBase的元数据,HMater是HBase的管理节点,ReginServer有多个,每个ReginServer管理了多个Regin,每个ReginServer根据列族的个数可以有多个Store,每个Store的MemStore是写入缓冲区,但在写入MemStore之前还是会先写入预写日志(HLog),HLog文件还是会保存在HDFS上面,并且所有的Regin共用一个HLog实例。当缓冲区写满后会刷写为HFile,StoreFile只是对HFile的轻量封装,一个Store可以有多个StoreFile,HFile还是保存在HDFS之上。
那么回到CAP理论,单个Regin可以认为是一个分片。由于有ReginServer的存在,对数据的更新操作是可以满足一致性的,但是ReginServer存在单点故障,所以HBase对CAP理论的取舍是CP。
从以上HBase的架构模式我们得出,HBase最后的查询数据方式是用行健加列名去定位某个值(单元格)。
在 Hbase 中有两种服务器:
Master 服务器
RegionServer 服务器
一般一个 HBase 集群有一个 Master 服务器和几个 RegionServer 服务器。
Master 服务器负责维护表结构信息,实际的数据都存储在 RegionServer 服务器上.
另外, HBase 有一点很特殊:
客户端获取数据由客户端直连 RegionServer 的,所以你会发现Master挂掉之后你依然可以查询数据,但就是不能新建表了。
RegionServer 是直接负责存储数据的服务器。RegionServer 保存的表数据直接存储在 Hadoop 的 HDFS 上, 所以架构如下
RegionServer 非常依赖 ZooKeeper 服务,可以说没有 ZooKeeper 就没有 HBase。
ZooKeeper 在 HBase 中扮演的角色类似一个管家。ZooKeeper 管理了 HBase 所有RegionServer 的信息,包括具体的数据段存放在哪个 RegionServer 上。
客户端每次与 HBase 连接,其实都是先与 ZooKeeper 通信,查询出哪个RegionServer 需要连接,然后再连接 RegionServer。因此,以上的架构又可以拓展成如下所示:
这就是 Hbase 的整体架构
可能你们会想当然地觉得 Master 是 HBase 的领导,所有的数据、所有的操作都会经过它。
错!其实在HBase中Master的角色不像领导,更像是打杂的。
我们之前说过,客户端从 ZooKeeper 获取了 RegionServer 的地址后,会直接从RegionServer 获取数据。其实不光是获取数据,包括插入、删除等所有的数据操作都是直接操作 RegionServer,而不需要经过 Master。
Master 只负责各种协调工作(其实就是打杂),比如建表、删表、移动Region、合并等操作。它们的共性就是需要跨 RegionServer,这些操作由哪个 RegionServer 来执行都不合适,所以 HBase 就将这些操作放到了 Master 上了。
这种结构的好处是大大降低了集群对 Master 的依赖。而 Master 节点一般只有一个到两个,一旦宕机,如果集群对Master的依赖度很大,那么就会产生单点故障问题。
在 HBase 中,即使Master宕机了,集群依然可以正常地运行,依然可以存储和删除数据。
但是, 如果 Master 长时间宕机也是不行的, 毕竟他还是有一些工作需要做的.
1.为RegionServer分配Region 2.处理 RegionServer 故障转移 3.当RegionSever失效的时候,协调对应Hlog的拆分 4.发现失效的Region,并将失效的Region转移到正常的RegionServer上5.在空闲时间进行数据的负载均衡 6.通过 Zookeeper 发布自己的位置给客户端
当客户端从 ZooKeeper 获取 RegionServer 的地址后,它会直接从 RegionServer获取数据。
优点类似于 Hadoop 中的 DataNode
HRegionServer内部管理了一系列HRegion对象,每个HRegion对应Table 中的一个Region
HRegionServer:
1) HRegionServer主要负责响应用户I/O请求,向HDFS文件系统中读写数据,是HBase中最核心的模块。
2) HRegionServer内部管理了一系列HRegion对象,每个HRegion对应了Table中的一个Region,HRegion中由多个HStore组成。每个HStore对应了Table中的一个Column Family的存储,可以看出每个Column Family其实就是一个集中的存储单元,因此最好将具备共同IO特性的column放在一个Column Family中,这样最高效。
HRegion:
HBase自动把表水平划分成多个区域(Region),每个region会保存一个表里面某段连续的数据;每个表一开始只有一个region,随着数据不断插入表,region不断增大,当增大到一定阈值的时候,region就会等分为两个新的region(裂变);当table中的行不断增多,就会有越来越多的region。这样一张完整的表被保存在多个RegionServer上。
HStore(一个HStore对应一个列族):
HStore是HBase存储的核心,其中由两部分组成:一个MemStore,有多个StoreFile
一个region由多个store组成,一个store对应一个CF(列族);store包括位于内存中的memcache和位于磁盘的storefile,写操作先写入memstore,当memstore中的数据达到某个阈值,hregionserver会启动flashcache进程写入storefile,每次写入形成单独的storefile;当storefile文件的数量增长到一定阈值后,系统会进行合并(minor,major compaction),在合并过程中会进行版本合并和删除工作(majar),形成更大的storefile;当一个region中所有的storefile的大小和数量超过一定阈值后,会把当前的region分割成为两个,并由hmaster分配到相应regionserver服务器,实现负载均衡;客户端检索数据,先在memstore里面找,找不到在storefile里面找。
Memstore & StoreFile
Client写入->存入MemStore,一直到MemStore满-> Flush成一个StoreFile,直至增长到一定阀值-> 触 发Compact合并操作-> 多个StoreFile Compact后,逐步形成越来越大的StoreFile ->单个StoreFile大小超过一定阀值后,触发Split操作,把当前Region Split成2个Region,当前Region会下线,新Split出的2个孩子Region会被HMaster分配到相应的HRegionServer上,使得原先1个Region的压力得以分流到2个Region上。
HBase只是增加数据,所有的更新和删除操作,都是在Compact阶段做的,所以,用户写操作只需要进入到内存即可立即返回,从而保证I/O高性能。
HLog:
在分布式系统环境中,无法避免系统出错或者宕机,因此一旦HRegionServer意外退出,MemStore中的内存数据将会丢失,这就需要引入HLog了。每个HRegionServer中都有一个HLog对象,HLog是一个实现Write Ahead Log的类,在每次用户操作写入MemStore的同时,也会写一份数据到HLog文件中(HLog文件格式见后续),HLog文件定期会滚动出新的,并删除旧的文件(已持久化到StoreFile中的数据)。当HRegionServer意外终止后,HMaster会通过Zookeeper感知到,HMaster首先会处理遗留的 HLog文件,将其中不同Region的Log数据进行拆分,分别放到相应region的目录下,然后再将失效的region重新分配,领取 到这些region的HRegionServer在Load Region的过程中,会发现有历史HLog需要处理,因此会Replay HLog中的数据到MemStore中,然后flush到StoreFiles,完成数据恢复。
* WAL意为Write ahead log,类似于MySQL中的binlog,用来做灾难恢复。
* Hlog记录数据的所有变更,一旦数据修改,就可以从log中进行恢复。每个HRegionServer维护一个HLog,
而不是每个HRegion一个。
这样不同Region(来自不同table)的日志会混在一起,
这样做的目的是不断追加单个文件,相对于同时写多个文件而言,
可以减少磁盘寻址次数,因此可以提高对table的写性能。
带来的麻烦是,如果一台HRegionServer下线,为了恢复其上的region,
需要将HRegionServer上的log进行拆分,然后分发到其它HRegionServer上进行恢复。
1.负责存储 HBase 的实际数据 2.处理分配给它的 Region 3.刷新缓存到 HDFS 4.维护 Hlog 5.执行压缩 6.负责处理 Region 分片
Region 就是一段数据的集合。
HBase中的表一般拥有一个到多个 Region。
Region有以下特性:
Region 不能跨服务器,一个 RegionServer 上有一个或者多个 Region。
数据量小的时候,一个 Region 足以存储所有数据;但是,当数据量大的时候,HBase会拆分 Region。
当 HBase 在进行负载均衡的时候,也有可能会从一台 RegionServer 上把 Region移动到另一台 RegionServer 上。
Region 是基于 HDFS 的,它的所有数据存取操作都是调用了 HDFS 的客户端接口来实现的。
HBase中有两张特殊的表,-ROOT- 和 .META. ,它们的功能如下:
-ROOT- 记录.META.表的Region信息,只有一个Region
.META. 记录用户表的Region信息,可以有多个Region
HBASE如何找到某个人Row Key(或者某个Row Key Range)所在的Region呢?使用三层类似B+树的结构来保存Region位置。元数据表 -Root- 和 .META. 都是HBase中的表。-ROOT- 表的Region被设定为永不拆分,意味着只有一个Region,-ROOT- 保存了 .META. 的region信息,而 .META. 保存了用户表的Regin信息。
1)Root Region永远不会被split,保证最多需要三次跳转,就能定位到任意Regin
2) .META. 表每行保存一个Region的位置信息,Row key采用“表名+表的最后一行”编码而成。假设 .META. 表的一行在内存中大约占用 1KB,并且每个 Regin限制为128M,上面的三层架构可以存储的Region数目为:
(128MB/ 1KB)* (128MB/1KB) =2^34 个Region
3)为了加快访问, .META. 表的全部Region都保存在内存中
client会将查询过的位置信息保存起来,缓存不会主动失效,因此如果Client上的缓存全部失效,则需要进行6次网络来回,才能点位到正确的Region(其中三次用来发现缓存失效,另外三次用来获取位置信息)
在zookeeper quorum中,除了存储 -ROOT-表的地址和HMaster的地址外,HRegionServer也会以Ephemeral(短暂)方式自己注册到zookeeper中,使得HMaster可以随时感知到各个HRegionserver的健康状态。此外,zookeeper也避免了HMaster的单点问题。
HBase通过Zookeeper来做master的高可用、RegionServer的监控、元数据的入口以及集群配置的维护等工作。具体工作如下:
通过Zoopkeeper来保证集群中只有1个master在运行,如果master异常,会通过竞争机制产生新的master提供服务
通过Zoopkeeper来监控RegionServer的状态,当RegionSevrer有异常的时候,通过回调的形式通知Master RegionServer上下线的信息
通过Zoopkeeper存储元数据的统一入口地址
1.监控 RegionServer 2 存储 Region 定位信息 3.HBase通过Zookeeper来做master的高可用