Hbase的架构简单解析
[TOC]
Hbase内部的基本组成
Hbase的整体主要由zookeeper,Hmaster,HRegionServer,Hdfs文件系统组成。由这四部分共同完成数据的读取与写入。
我们知道,hbase有个很重要的特性,可以通过分布式集群存取海量数据,当数据量越来越多的时候通过增加集群主机的数量就可以将数据分散到不同的主机上,这是传统的数据库很难实现的,那么hbase是如何做到的呢?下面我们就来解析下hbase的基本架构原理。
Hbase数据的存储方式
对hbase有一点了解的童鞋都应该知道,hbase不同与传统的数据库,它是一种列式存储的数据库,对于里面的每一张表,每一行的数据都有一个rowkey,在数据库中的数据都是按照rowkey顺序排列的。所以可以将每张表的数据按照rowkey进行划分:
不同的范围的数据划分到不同的地方(hbase中的这个地方被称为HRegion),不同的HRegion被放在不同的主机上,当查询数据的时候,只要根据rowkey先找到数据在那个范围的HRegion中,就可以直接到那个HRegion中找到数据,所以查询效率会比传统的数据库快很多。
基本就像上图这样,随着数据不断增多,Region也会不断的增多(对表的划分增多),不同的Region由多个不同的RegionServer管理着。
Hbase读写数据的基本流程
写数据
- 首先要找到管理相应Region的RegionServer(但是如何找到RegionServer的呢?这个会在读取数据哪里解释),然后发送写数据的请求。
- 当RegionServer收到请求后,首先会将请求写入到HLog中(防止数据意外丢失,很多系统都是利用的这种机制)。
- 在Hlog写入完成之后,在找到相应的Region将数据写入。
那么问题来了?在Region内部又是如何将数据写入到hdfs中的呢?这里就涉及到Region内部的数据持久化机制了:
在Region内部,当数据操作请求由RegionServer传到Region的时候,Region中包含了很多的Store(每个Store对应了一个Table在这个Region中的一个Column Family,即每个Column Family就是一个集中的存储单元),写入数据根据具体在那个Column Family,将数据传到具体的Store中。数据传输流程如下:
- RegionServer首先会将数据写入到MemStore内存中,这时返回客户端通知说已经写入成功了。
- 当MemStore中的数据达到一定大小的时候,会有一次flush的过程,在此过程中,数据会被写入StoreFile文件中。然后StoreFile又会被序列化为HFile文件。(备注:在写入MemStore的时候会被插入到指定的顺序中,所以是有序的)
- HFile之后通过Hdfs的api上传到hdfs中。
读数据流程
首先我们需要思考的是,要想读到数据,首先客户端肯定需要知道数据在哪吧。(写数据同样也是要先知道数据在哪),我们已经知道,hbase的数据都划分到了region中,那么我们如何找到相应的region呢?整体流程如下图:
- 首先我们要通过zookeeper找找到-root-的位置,这个root本质上也是一个region,不过里面存放的是不同范围的rowkey应该去那个RegionServer的
.meta.
中去查找 - 通过请求
.meta.
我们知道了我们需要的region在哪个RegionServer上,然后就可以去那个regionServer上去读数据了。
- 首先我们要通过zookeeper找找到-root-的位置,这个root本质上也是一个region,不过里面存放的是不同范围的rowkey应该去那个RegionServer的
注1:这里其实有个问题,为啥不直接把数据的region所在的信息写在-root-中,这样不就少一个流程了。加快了访问速度吗?主要是为了保存的数据量考虑,由于Region的数量可能会有很多,而-root-只能由一个,所以防止-root-的内存被撑爆,所以多加了一层。
注2:不过一般公司的数据真的有这么多吗?应该是没有的吧,因而在HBase 0.96以后去掉了-ROOT- Table,只剩下这个特殊的目录表叫做Meta Table(hbase:meta),它存储了集群中所有用户HRegion的位置信息,而ZooKeeper的节点中(/hbase/meta-region-server)存储的则直接是这个Meta Table的位置
Hmaster是干嘛的?
在上面的读写流程中,我们已经提到了HRegionServer,hdfs,zookeeper的作用了,但是一直都没有提到Hmaster,这个听上去很像老大的东西到底是干嘛的呢?难道只是打酱油的?Ofcource Not!
之前我们虽然已经知道了数据是如何存入的,但是有一个问题一直没说,那就是hbase为啥可以管理海量数据呢?当数据越来越多的时候,是谁来负责将数据进行划分为更小的区域的呢?那就是一直在默默奉献额老大——HMaster。
Hmaster是如何管理数据的呢?
清理冗余的数据
当同一region的数据块达到四块的时候,Hmaster会对其进行一次数据合并,清理期中的冗余数据。合并之后的数据会小于256M。
HRegion Split
- 最初,一个Table只有一个HRegion,随着数据写入增加,如果一个HRegion到达一定的大小,就需要Split成两个HRegion,这个大小由hbase.hregion.max.filesize指定。这个Split过程就是由Hmaster完成的。
- 当split时,两个新的HRegion会在同一个HRegionServer中创建,它们各自包含父HRegion一半的数据,当Split完成后,父HRegion会下线,而新的两个子HRegion会向HMaster注册上线,处于负载均衡的考虑,这两个新的HRegion可能会被HMaster分配到其他的HRegionServer中。
当HRegionServer宕机之后,hmaster可以读取hlog,将数据在发送给其他RegionServer进行数据恢复。并修改
.meta.
注:RegionServer不管理Hbase的元数据,元数据由Zookeeper管理。
总结一下
Hbase中各个主要部分的功能:
Hmater
- 在Region Split后,负责新Region的分配;
- 新机器加入时,管理HRegion Server的负载均衡,调整Region分布
- 在HRegion Server宕机后,负责失效HRegion Server 上的Regions迁移。
Region Server
- Region server维护Master分配给它的region,处理对这些region的IO请求
- HRegion Server管理了很多table的分区,也就是region。
zookeeper
- ZooKeeper为HBase集群提供协调服务,它管理着HMaster和HRegionServer的状态(available/alive等),并且会在它们宕机时通知给HMaster
- zookeeper中管理着hbase的元数据,例如-root-的位置所在。
hdfs
- 数据文件的存放处。由于其本身的分布式存储机制,所以数据文件很安全。
- hadoop的datanode最好和region在同一主机上,方便读取数据。尽量避免网络数据传输。