第五章:HBase架构

HBase

第五章:HBase架构


文章目录

一、HBase逻辑存储模型

二、HBase架构

(1) HMaster

(2) HRegionServer

(3) HRegion

(4)MemStore

(5) HLog

(6) HFile

(7)StoreFile

三、HBase写流程

四、刷写

(1)自动刷写的时机

(2)手动刷写

五、读流程

六、Compaction

(1)Minor Compaction的验证

(2)Major Compaction



一、HBase逻辑存储模型

在之前的文章中已经讲过,现在简单的复习一下

HBase以表的形式 存储数据,表由行和列组成。列划分为若干个列族。

RowKey:Hbase使用Rowkey来唯一的区分某一行的数据。

列族:Hbase通过列族划分数据的存储,列族下面可以包含任意多的列,且HBase的存储是稀疏的。

时间戳:TimeStamp对Hbase来说至关重要,因为它是实现Hbase多版本的关键。在Hbase中使用不同的timestame来标识相同rowkey不同版本的数据。

Cell:HBase 中由 rowkey 和 columns 确定的一个存储单元称为 cell。每个 cell 都保存着一份数据的多个版本。版本通过时间戳来索引。cell中的数据是没有类型的,是按字节码形式存储。


二、HBase架构

其中Client为客户端

HBase底层依赖HDFS,通过DFS Cilent进行HDFS操作。HMaster负责把HRegion分配给HRegionServer,每一个HRegionServer可以包含多个HRegion,多个HRegion共享HLog,HLog用来做灾难恢复。每一个HRegion由一个或多个Store组成,一个Store对应表的一个列族,每个Store中包含与其对应的MemStore以及一个或多个StoreFile(是实际数据存储文件HFile的轻量级封装),MemStore是在内存中的,保存了修改的数据,MemStore中的数据写到文件中就是StoreFile。

(1) HMaster

    HMaster的主要功能有:
①把HRegion分配到某一个RegionServer。
②有RegionServer宕机了,HMaster可以把这台机器上的Region迁移到active的RegionServer上。
③对HRegionServer进行负载均衡。
④通过HDFS的dfs client接口回收垃圾文件(无效日志等)
注:HMaster没有单点问题,HBase中可以启动多个HMaster,通过Zookeeper的Master Election机制保证总有一个Master运行

(2) HRegionServer

    ①维护HMaster分配给它的HRegion,处理对这些HRegion的IO请求,也就是说客户端直接和HRegionServer打交道。(从图中也能看出来)
    ②负责切分正在运行过程中变得过大的HRegion

(3) HRegion

    下面我们看看HRegion的结构:

       每个HRegion由多个Store构成,每个Store保存一个列族(Columns Family),表有几个列族,则有几个Store,每个Store由一个MemStore和多个StoreFile组成,MemStore是Store在内存中的内容,写到文件后就是StoreFile。StoreFile底层是以HFile的格式保存。

(4)MemStore

写缓存,由于 HFile 中的数据要求是有序的,所以数据是先存储在 MemStore 中排序。MemStore 数据容量有限,当达到一个阈值后,则把数据写入磁盘文件 StoreFile 中后,在 HLog 文件中写入一个标记,表示 MemStore 缓存中的数据已被写入 StoreFile 中。如果 MemStore 中的数据丢失,则可以从 HLog 上恢复。

(5) HLog

       HLog也称为WAL,WAL意为write ahead log(预写日志),由于数据要经 MemStore 排序后才能刷写到 HFile,但把数据保存在内存中会有很高的 概率导致数据丢失,为了解决这个问题,数据会先写在Hlog中,然后再写入 MemStore 中。所以在系统出现故障的时候,数据可以通过这个日志文件重建。 用来做灾难恢复使用,HLog记录数据的变更,包括序列号和实际数据,所以一旦region server 宕机,就可以从log中回滚还没有持久化的数据。

(6) HFile

HBase的数据最终是以HFile的形式存储在HDFS中的,HBase中HFile有着自己的格式。

(7)StoreFile

保存实际数据的物理文件,StoreFile HFile 的形式存储在 HDFS 上。每个 Store 会有 一个或多个 StoreFileHFile),数据在每个 StoreFile 中都是有序的。


三、HBase写流程

写流程:

(1)Client 先访问 zookeeper,获取 hbase:meta 表位于哪个 Region Server中。 


(2)访问对应的 Region Server,获取 hbase:meta 表,根据读请求的 namespace:table/rowkey查询出目标数据位于哪个 Region Server 中的哪个 Region 中。并将该 table region 信息以 meta 表的位置信息缓存在客户端的 meta cache,方便下次访问。 

(3)与目标 Region Server 进行通讯; 

(4)将数据顺序写入(追加)到 WAL

(5)将数据写入对应的 MemStore,数据会在 MemStore 进行排序;

(6)向客户端发送 ack

(7)等达到 MemStore 的刷写时机后,将数据刷写到 HFile


四、刷写

(1)自动刷写的时机

①当memstore的大小达到128(默认值)时:

<!-- 单个region里memstore的缓存大小,超过那么整个HRegion就会flush,默认128M -->  
    <property>  
        <name>hbase.hregion.memstore.flush.size</name>  
        <value>134217728</value>  
        <description>  
            Memstore will be flushed to disk if size of the memstore  
            exceeds this number of bytes. Value is checked by a thread that runs  
            every hbase.server.thread.wakefrequency.  
        </description>  
    </property> 

②当region server memstore 的总大小达到堆大小的40%(默认值)时,会按memstore大小顺序依次刷写

<!-- regionServer的全局memstore的大小,超过该大小会触发flush到磁盘的操作,默认是堆大小的40%,而且regionserver级别的   
        flush会阻塞客户端读写 -->  
    <property>  
        <name>hbase.regionserver.global.memstore.size</name>  
        <value></value>  
        <description>Maximum size of all memstores in a region server before  
            new  
            updates are blocked and flushes are forced. Defaults to 40% of heap (0.4).  
            Updates are blocked and flushes are forced until size of all  
            memstores  
            in a region server hits  
            hbase.regionserver.global.memstore.size.lower.limit.  
            The default value in this configuration has been intentionally left  
            emtpy in order to  
            honor the old hbase.regionserver.global.memstore.upperLimit property if  
            present.  
        </description>  
    </property> 

③当达到自动刷写时间时,也会自动触发刷写(默认1小时)

<!-- 内存中的文件在自动刷新之前能够存活的最长时间,默认是1h -->  
    <property>  
        <name>hbase.regionserver.optionalcacheflushinterval</name>  
        <value>3600000</value>  
        <description>  
            Maximum amount of time an edit lives in memory before being automatically  
            flushed.  
            Default 1 hour. Set it to 0 to disable automatic flushing.  
        </description>  
    </property> 

(2)手动刷写

hbase(main):073:0> flush

ERROR: wrong number of arguments (0 for 1)

Here is some help for this command:
Flush all regions in passed table or pass a region row to
flush an individual region.  For example:

  hbase> flush 'TABLENAME'
  hbase> flush 'REGIONNAME'
  hbase> flush 'ENCODED_REGIONNAME'

五、读流程

1Client 先访问 zookeeper,获取 hbase:meta 表位于哪个 Region Server

2)访问对应的 Region Server,获取 hbase:meta 表,根据读请求的 namespace:table/rowkey查询出目标数据位于哪个Region Server 中的哪个 Region 中。并将该 table region 信息以 meta 表的位置信息缓存在客户端的 meta cache,方便下次访问。

3)与目标 Region Server 进行通讯;

4)分别在 Block Cache(读缓存),MemStore Store FileHFile)中查询目标数据,并将 查到的所有数据进行合并。此处所有数据是指同一条数据的不同版本(time stamp)或者不 同的类型(Put/Delete)。

5) 将从文件中查询到的数据块(BlockHFile 数据存储单元,默认大小为 64KB)缓存到 Block Cache

6)将合并后的最终结果返回给客户端。


六、Compaction

由于memstore每次刷写都会生成一个新的HFile,且同一个字段的不同版本(timestamp和不同类型(Put/Delete)有可能会分布在不同的 HFile 中,因此查询时需要遍历所有的 HFile。为了减少 HFile 的个数,以及清理掉过期和删除的数据,HBase会定期合并数据。

Compaction 分为两种,分别是 Minor Compaction Major CompactionMinor Compaction 会将临近的若干个较小的 HFile 合并成一个较大的 HFile,但不会清理过期和删除的数据Major Compaction 会将一个 Store 下的所有的 HFile 合并成一个大HFile,并且清理掉过期 和删除的数据

(1)Minor Compaction的验证

先写入一些数据:

hbase(main):004:0> put 'stu','1001','info:name','zhangsan'
0 row(s) in 1.2680 seconds

hbase(main):005:0> put 'stu','1001','info:name','lisi'
0 row(s) in 0.5350 seconds

hbase(main):008:0> scan 'stu',{RAW=>true,VERSIONS=>10}
ROW                                                    COLUMN+CELL                                                                                                                                                     
 1001                                                  column=info:name, timestamp=1602924007558, value=lisi                                                                                                           
 1001                                                  column=info:name, timestamp=1602923993852, value=zhangsan                                                                                                       
1 row(s) in 0.0340 seconds

hbase(main):009:0> scan 'stu'
ROW                                                    COLUMN+CELL                                                                                                                                                     
 1001                                                  column=info:name, timestamp=1602924007558, value=lisi                                                                                                           
1 row(s) in 0.0200 seconds

现在手动flush,写入内存

hbase(main):010:0> flush 'stu'
0 row(s) in 6.2710 seconds

看到数据已经进入内存中,再scan:

hbase(main):011:0> scan 'stu',{RAW=>true,VERSIONS=>10}
ROW                                                    COLUMN+CELL                                                                                                                                                     
 1001                                                  column=info:name, timestamp=1602924007558, value=lisi                                                                                                           
1 row(s) in 0.0980 seconds

发现只剩下一个数据,之前说过创建表后有一个VERSIONS值用以设置数据的版本数,之前可以看到是没写入内存中。

此时再插入一个数据,再flush会如何?

hbase(main):012:0> put 'stu','1001','info:name','wangwu'
0 row(s) in 0.0290 seconds

hbase(main):013:0> scan 'stu',{RAW=>true,VERSIONS=>10}
ROW                                                    COLUMN+CELL                                                                                                                                                     
 1001                                                  column=info:name, timestamp=1602924477771, value=wangwu                                                                                                         
 1001                                                  column=info:name, timestamp=1602924007558, value=lisi                                                                                                           
1 row(s) in 0.0170 seconds

hbase(main):014:0> flush 'stu'
0 row(s) in 0.5700 seconds

hbase(main):015:0> scan 'stu',{RAW=>true,VERSIONS=>10}
ROW                                                    COLUMN+CELL                                                                                                                                                     
 1001                                                  column=info:name, timestamp=1602924477771, value=wangwu                                                                                                         
 1001                                                  column=info:name, timestamp=1602924007558, value=lisi                                                                                                           
1 row(s) in 0.0170 seconds

发现此时并没有删除旧的数据,看了一下HDFS

发现有两个文件,说明每次flush都会生成一个Hfile,且只有在同一个Hfie中的旧版本数据才会被删除

此时Minor Compaction即compact!

hbase(main):022:0> compact 'stu'
0 row(s) in 0.5900 seconds

此时最下面的文件就是合并以后的文件,其它文件过2-3分钟后就会被删除,此时再scan一下:

hbase(main):029:0> scan 'stu',{RAW=>true,VERSIONS=>10}
ROW                                                    COLUMN+CELL                                                                                                                                                     
 1001                                                  column=info:age, timestamp=1602925207850, value=10                                                                                                              
 1001                                                  column=info:name, timestamp=1602924477771, value=wangwu                                                                                                         
1 row(s) in 0.0200 seconds

发现旧数据被删除了

那能不能删除type标记呢?验证一下

hbase(main):034:0> delete 'stu','1001','info:age'
0 row(s) in 0.2800 seconds

hbase(main):035:0> scan 'stu',{RAW=>true,VERSIONS=>10}
ROW                                                    COLUMN+CELL                                                                                                                                                     
 1001                                                  column=info:age, timestamp=1602925507259, type=DeleteColumn                                                                                                     
 1001                                                  column=info:age, timestamp=1602925207850, value=10                                                                                                              
 1001                                                  column=info:name, timestamp=1602924477771, value=wangwu                                                                                                         
 1002                                                  column=info:age, timestamp=1602925474735, value=20                                                                                                              
 1002                                                  column=info:name, timestamp=1602925443861, value=xiaobai                                                                                                        
2 row(s) in 0.0360 seconds

合并后:

hbase(main):036:0> compact 'stu'
0 row(s) in 0.0470 seconds

hbase(main):037:0> scan 'stu',{RAW=>true,VERSIONS=>10}
ROW                                                    COLUMN+CELL                                                                                                                                                     
 1001                                                  column=info:age, timestamp=1602925507259, type=DeleteColumn                                                                                                     
 1001                                                  column=info:age, timestamp=1602925207850, value=10                                                                                                              
 1001                                                  column=info:name, timestamp=1602924477771, value=wangwu                                                                                                         
 1002                                                  column=info:age, timestamp=1602925474735, value=20                                                                                                              
 1002                                                  column=info:name, timestamp=1602925443861, value=xiaobai                                                                                                        
2 row(s) in 0.0130 seconds

发现type并没有被删除,看文件系统,发现文件确实合并了。说明Minor Compaction并不能删除type标记

(2)Major Compaction

hbase(main):002:0> major_compact 'stu'
0 row(s) in 0.1040 seconds

hbase(main):009:0> scan 'stu',{RAW=>true,VERSIONS=>10}
ROW                                                    COLUMN+CELL                                                                                                                                                     
 1001                                                  column=info:name, timestamp=1602924477771, value=wangwu                                                                                                         
 1002                                                  column=info:age, timestamp=1602925474735, value=20                                                                                                              
 1002                                                  column=info:name, timestamp=1602925443861, value=xiaobai                                                                                                        
 1003                                                  column=info:age, timestamp=1602925987881, value=30                                                                                                              
 1003                                                  column=info:name, timestamp=1602926011697, value=xiaohei                                                                                                        
3 row(s) in 0.1680 seconds

发现Delete标记被删除了。

猜你喜欢

转载自blog.csdn.net/tyh1579152915/article/details/109133676