vlambda博客
学习文章列表

HBase架构组成及原理

HBASE组成

回顾一下HBASE教程前两篇文章提到的内容,第一篇中我们提到,HBASE以HDFS作为存储。第二篇中,我们在配置文件中配置了ZK的目录、并且我们看到HBASE启动的时候会有HMater和HRegionserver。那么不难得出,HBASE的组件:

HDFS

  • HDFS为Hbase提供底层数据存储服务,元数据和表数据都存储在HDFS中,同时为Hbase提供高可用(Hlog存储在HDFS)的支持.

  • HDFS数据多副本机制能保证HBASE的高可靠性。

HMaster

  • 管理HRegionServer:为RegionServer分配Region,当RegionSever失效的时候,协调对应Hlog的拆分,将失效的Region分配到正常的RegionServer上。

  • 维护集群的元数据信息,维护集群负载均衡。

HRegionServer

  • 直接对接来自客户端的读写请求,是真正的“干活”的节点,比如表的增删改查数据,和hdfs交互,存取数据。

  • 管理master为其分配的Region。

  • 负责和底层HDFS的交互,存储数据到HDFS。

  • 负责Region变大以后的拆分。

  • 负责Storefile的合并工作。

Zookeeper

  • Zookeeper管理HregionServer,监控RegionServer的状态、当RegionSevrer有异常的时候,通过回调的形式通知Master RegionServer上下限的信息。

  • 因为你读取数据所需要的元数据表在ZK上。

HBASE架构

  • 首先HBASE中的Table是会分成Region的,比如,user表中有10条记录,那么可能前5条在一个region中,后5条在另一个region里,类似于分区的概念,分布式系统中到处可见分区,下篇会具体讲解HBASE中的region。

  • Hmaster会为HRegionServer分配region,分配后Region落地到HRegionServer上,即图中的HRegion。

  • HRegionServer除了由HRegion组成外,还有一个很重要的东西:HLOG。

    HBASE所有涉及到数据的变更都会写到HLOG中。

    它的作用就是保证数据安全。

    当RegionServer出现问题的时候,能跟进Hlog来做数据恢复。

  • HRegion由store(memstore,storefile(hfile))组成。

    写文件时并不直接写入HDFS,而是先停留在MemStore缓冲区,达到一定的量再Flush到StoreFile中,StoreFile是存储HFile的地方,而HFile是真正存储数据的文件。



现在具体来讲解这些组件:

MemStore

MemStore是内存缓冲区,HBASE写入数据的时候会先停留在MemStore中,达到一定的时候才会刷盘到StoreFile中。


为什么要有MemStore的存在呢?

1、不需要立即写入hdfs,先写内存,内存满了再写hdfs。可以提高写的性能
2、可以进行排序。HBASE写入到hdfs上的数据是需要按照rowkey进行排序的,而Hbase是随机的读写,因此hbase通过memstore在持久化到HDFS之前完成排序,然后再快速的顺序写入HDFS。主要原理是LSM,有兴趣可以了解下。
3、优化数据的存储,比如一个记录添加之后马上被删除了,在flush的时候就可以直接不把这个数据写到HDFS中。

为什么要达到一定的时候再刷盘?

那是为了提高Hbase的写入性能,所以当写请求写入MemStore后,不会立即刷盘。那么哪些场景会触发刷盘的操作呢?总结如下:

  • Region级别的触发刷写


    hbase.hregion.memstore.flush.size


    当MemStore的大小达到hbase.hregion.memstore.flush.size大小的时候会触发刷盘,默认128M。

  • 全局内存控制


    hbase.regionserver.global.memstore.size //这个全局的参数是控制内存整体的使用情况,当所有memstore占整个heap的最大比例的时候,会触发刷盘的操作。

    默认40%。


    hbase.regionserver.global.memstore.size.lower.limit //上面这个参数并不代表所有的memstore都要进行刷盘,所以还要有一个全局memstore刷写下限,默认0.95。


    举例,比如你配置的hbase.regionserver.global.memstore.size.lower.limit=0.95 hbase.regionserver.global.memstore.size=0.4,堆内存总共是64G,那么


    触发刷写的阈值是:

    64*0.4*0.95=6.08
    触发阻塞的阈值是:

    64*0.4=6.4

  • HLog引发的刷盘


    HLOG中包含了所有已经写入Memstore但还未Flush到HFile的更改。

    在Memstore中数据还没有持久化,当RegionSever宕掉的时候,可以使用HLOG恢复数据。

    可是当HLog很大的时候,恢复的时候就需要很长的时间。

    因此,对HLOG的大小也有一些限制,当达到这些限制的时候,就会触发Memstore的flush。

    Memstore flush会使HLOG减少,因为数据持久化之后(写入到HFile),就没有必要在HLOG中再保存这些修改了。

    有两个属性可以配置:


    hbase.regionserver.hlog.blocksize//hlog块大小


    hbase.regionserver.maxlogs//Hlog的最大个数


    这两个相乘就决定了hlog的最大大小。

HLOG

Hlog是Hbase实现WAL(Write ahead log)方式产生的日志信息,内部是一个简单的顺序日志。每个RegionServer对应1个Hlog(备注:1.x版本的可以开启MultiWAL功能,允许多个Hlog),因此是多个Region对应同一个HLOG。所有对于该RegionServer的写入都被记录到Hlog中。Hlog功能就是为了保证数据安全。当RegionServer出现问题的时候,能跟进Hlog来做数据恢复
数据到达Region是先写入WAL然后再被加载到MemStore中的。
HLog持久化在HDFS之上, HLog存储位置查看:

我们看到,有一个oldWAL目录,这是啥?刚刚提到,为了避免恢复的时候因为HLOG过大导致的效率低下,HLOG过大时就会触发强制刷盘操作。对于已经刷盘的数据,其对应的Hlog会过期,过期的HLOG会被移动到oldWAL。
HLOG架构图:

由图可知,Hlog=Hlogkey+WALEdit。Hlogkey=sequenceid+timestamp+cluster ids+regionname+tablename等组成,WALEdit是由一系列的KeyValue组成。
其中sequenceid非常重要,sequenceid是一个自增序列号,region的数据恢复和Hlog过期清除都要依赖它。
Hlog的过期依赖于对sequenceid的判断。Hbase会将Hlog的sequenceid和Hfile最大的sequenceid(刷新到的最新位置)进行比较,如果该Hlog文件中的sequenceid比刷新的最新位置的sequenceid都要小,那么这个Hlog就过期了,过期了以后,对应Hlog会被移动到oldWAL目录。
当RegionServer出现故障的时候,需要对Hlog进行回放来恢复数据。回放的时候会读取Hfile的sequenceid和Hlog中的sequenceid进行比较,小于sequenceid的就直接忽略,大于等于的就进行重做。回放完成后,就完成了数据的恢复工作。举例,HFile中sequenceid=10,HLOG中sequenceid=15,1-10的在HFile中已经持久化了就不需要恢复了,那么就是恢复11-15的数据。


如何打开和关闭WAL
默认是打开的。Mutation.setDurability(Durability.SKIP_WAL)可以关闭它。这样可以让数据操作快一点,但是最好不要这么做,因为当服务器宕机,数据会丢失。

WAL滚动
WAL是一个环状的滚动日志结构,这样可以保证写入效果最高并且保证空间不会持续变大。
触发滚动的条件:
1、WAL的检查间隔:hbase.regionserver.logroll.period。默认一小时,上面说了,通过sequenceid,把当前WAL的操作和HDFS对比,看哪些操作已经被持久化了。就被移动到oldWAL目录中。
2、当WAL文件所在的块block快要满了
3、当WAL所占的空间大于或者等于某个阈值(hbase.regionserver.hlog.blocksize乘hbase.regionserver.logroll.multiplier)blocksize是存储系统的块大小,如果你是基于HDFS只要设定为HDFS的块大小即可,multiplier是一个百分比,默认0.95,即WAL所占的空间大于或者等于95%的块大小,就被归到oldWAL文件中。


oldWAL何时删除
oldWAL什么时候被彻底删除呢?Master会定期的去清理这个文件,如果当这个WAL不需要作为用来恢复数据的备份,那么就可以删除。两种情况下,可能会引用WAL文件,此时不能删除
1、TTL进程:该进程会保障WAL文件存活到hbase.master.logcleaner.ttl定义的超时时间为止,默认10分钟。
2、备份机制:如果你开启了备份机制replication(把一个集群的数据实时备份到里另一个集群),那么HBASE要保障备份集群已经完全不需要这个文件了。如果你手头就一个集群,那么就不需要考虑这个文件了

StoreFile和HFile

StoreFile是对HFile进行了轻量级的包装。HFile是实际数据的存储。
HFile包括:

  • Data:数据块

  • Meta:

    元数据块

  • Fileinfo:

    文件信息

  • DataIndex:

    Data块索引信息

  • MetaIndex:

    Meta块索引信息

  • Trailer:

    存储了Fileinfo Dataindex Metaindex的偏移值

相信读到这里,读者还是会云里雾里摸不着头闹,没有关系,目前只需要有一个大概的印象,但等你学完全套教程之后,务必再回到这篇文章仔细感悟。