HBase存储原理、读写原理
HBase存储原理(架构)
HBase依赖于Zookeeper和Hadoop的,所以在启动HBase前需要启动Zookeeper和Hadoop。
HMaster用于管理整个HBase集群,即管理每个HRegionServer,它掌握着整个集群的元数据信息,同时会将相应的数据存储到Zookeeper(元数据信息、高可用信息等)。
-
HMaster的职责: -
1)管理用户对Table的增、删、改、查操作; -
2)记录region在哪台Hregion server上; -
3)在Region Split后,负责新Region的分配; -
4)新机器加入时,管理HRegion Server的负载均衡,调整Region分布; -
5)在HRegion Server宕机后,负责失效HRegion Server上的Regions迁移。
HRegionServer是每台机器上的一个Java进程(一台机器只有一个HRegionServer进程),用来处理客户端的读写请求(和Hadoop的DataNode类似),并维护着元数据信息。
-
HRegionServer的职责: -
1)HRegion Server主要负责响应用户I/O请求,向HDFS文件系统中读写数据,是HBASE中最核心的模块。 -
2)HRegion Server管理了很多table的分区,也就是region。
每个HRegionServer有一个HLog(有且仅有一个)。HLog是操作日志,用来做灾难恢复的,当客户端发起一个写请求时,会先往HLog中写再往Memory Store中写。假设没有HLog,我们进行一个写请求,会首先写到Memory Store上,等到Memory Store到达一定容量后,才会flush到StoreFile中。但是如果在这之前主机断电了呢?那这部分操作的数据全丢失了。这显然不是我们想到的结果,于是就有了HLog。
每个HRegionServer里面有多个HRegion,一个HRegion对应于HBase的一张表(也可能是表的一部分,因为表太大了会切分,表和HRegion的对应关系是一对多),当这张表到一定大小的时候会进行切分,切分成两个HRegion,切分出来的新的HRegion会保存到另一台机器上。每个HRegionServer里面有多个HRegion,可以理解为有多张表。
每个HRegion里面有多个Store(一张表中有多个列族),一个Store对应于HBase一张表的一个列族,。按照这个原理,我们在设计列族的时候,可以把经常查询的列放在同一个列族,这样可以提高效率,因为同一个列族在同一个文件里面(不考虑切分)。
每个Store有一个内存级别的存储Memory Store(有且仅有一个)。当Memory Store达到一定大小或一定时间后会进行数据刷写(flush),写到磁盘中(即HFile)。
每个Store有多个磁盘级别的存储StoreFile,Memory Store每刷写一次就形成一个StoreFile,HFile是StoreFile在HDFS上的存储格式。
HBase读原理
在上图中,我们模拟一下客户端读取数据过程,假设Zookeeper存放的meta表在RS1机器上,meta表存放的内容如下,Student表行键范围在1~100的存放在RS4上,在101~200的存放在RS3上,等等。
客户端现在要读取Student表的第100行,具体步骤如下:
1. 客户端向Zookeeper发起请求,请求元数据所在RegionServer,Zookeeper集群存放的是HBase的meta表所在位置。
2. Zookeeper返回给客户端元数据所在RegionServer(即RS1)。
3. 客户端收到应答后去请求RS1,请求查询Student表的rowkey=100数据所在位置。
4. 在RS1上查询meta表可知该数据在RS4机器上,即返回给客户端rowkey所在位置(RS4)。
5. 客户端收到应答后去请求RS4读数据。
6. RS4查询数据返回给客户端。查询时先去内存(MemStore)查找,因为内存是最新的数据,如果找到了就返回结果,如果没找到则去缓存(cache)找,如果找到了就返回结果,如果还没找到就去磁盘(StoreFile)找,如果在磁盘找到了,则先将结果写入缓存(cache),再返回给客户端,写入缓存是为了下次查询提高效率。
可以发现,在整个读过程中HMaster并没有参与,即读流程与HMaster无关,所以如果HMaster挂了,也是可以读数据的。
HBase写原理
HBase的写是比读快的,为什么呢,看下面的写过程,同样假设Zookeeper存放的meta表在RS1机器上,meta表存放的内容如下,Student表行键范围在1~100的存放在RS4上,在101~200的存放在RS3上,等等。
客户端现在要插入数据给Student表,其中rowkey=100,具体步骤如下:
1. 客户端向Zookeeper发起请求,请求元数据所在RegionServer,Zookeeper集群存放的是HBase的meta表所在位置。
2. Zookeeper返回给客户端元数据所在RegionServer(即RS1)。
3. 客户端收到应答后去请求RS1,请求查询Student表的rowkey=100数据所在位置。
4. 在RS1上查询meta表可知该数据在RS2机器上,即返回给客户端rowkey所在位置(RS2)。
5. 客户端收到应答后去请求RS4写入数据。
6. RS2收到请求,先将数据写入HLog,再将数据写入MemStore,写入MemStore后就返回给客户端写入成功信息,此时,客户端的写流程完成了。
因为写入内存就结束了写流程,不用访问磁盘,所以总体比读流程是快一点的。
同样,在整个写流程中HMaster也没有参与,所以如果HMaster挂了,也是可以进行写数据的。但是,如果时间长了,表的大小一直变大,而HMaster却挂了,即不会触发Region切分,这样就会导致数据倾斜,系统就变得不安全了。
以进行写数据的。但是,如果时间长了,表的大小一直变大,而HMaster却挂了,即不会触发Region切分,这样就会导致数据倾斜,系统就变得不安全了。**