HBase原理深入: 读写数据流程及刷写、合并

HBase原理深入: 读写数据流程及刷写、合并

HBase读数据流程

在这里插入图片描述

整体流程介绍如下:
假设当客户端Client发送一个读数据的请求,请求获取到某一个表下给定Row_Key值的数据。此时该请求经过HBase处理的流程为:

  1. Client先访问zookeeper获取hbase:meta表位于哪个Region Server。
    首先,需要好好理解一下这一步进行的操作。我们知道,HBase是一个分布式的海量非关系型数据库系统,因为hbase的的某个数据表可能会包含海量的数据,此时利用分布式的特性,就需要对表进行切分。HBase在对表进行切分时,是以Region为单位进行切分的,每个Region可能被存放在不同的节点上。此时就需要知道或者说管理每个region在哪个节点上存储。因此就需要有元数据的概念,简单来说元数据就记录了分布式集群中每个节点所存储的数据信息。而由HBase的架构原理可以知道,HBase借助了Zookeeper来负责分配region,实现高可用,以及管理维护集群的元数据信息等功能。所以在ZK集群中记录了元数据信息又哪一个节点进行保存。而zk集群存储该信息的目录在/hbase/meta-region-server下,我们可以进到该目录查看一下里面的内容:
    在这里插入图片描述

虽然有一部分乱码,但是仍然可以看到有一个节点信息:linux122 (这是我部署的节点名称)。说明此时在我的HBase集群上,保存元数据信息的节点是linux122。
我们还可以通过HBase提供的Web页面进行验证:
在这里插入图片描述

这里也可以看到,HBase元数据表hbase:meta保存在节点linux122上。

最后再用官网上的描述来介绍hbase:meta元数据信息:

The hbase:meta table (previously called .META.) keeps a list of allregions in the system, and the location of hbase:meta is stored in ZooKeeper.

因此通过上面的描述,我们就可以了解为什么请求需要先去访问Zookeeper集群,而且这一步获取到的不是元数据信息,而是元数据表在哪个节点上(Region Server)上存储的。

  1. 就是获取到hbase:meta存储在哪个节点(Region Server)上,比如我这里的linux 122上

  2. 获取到元数据存储在哪个节点后,就需要访问对应节点拉取元数据信息。上面说,元数据信息记录了集群中各节点存储的数据信息。而HBase是如何利用元数据来完成最初的查询请求呢?
    对于这个问题,我们可以先来看一下HBase的元数据的内容,看看其到底记录了什么信息:
    在这里插入图片描述

    这里我截取了一小部分的内容,显示的是对于某张表"friend",元数据内记录的信息。首先可以直观的看到,column=info:server这一单元格内记录的值是linux121:16020,这说明保存该"friend"表的region在linux121节点上存储。这里要特别注意第一行,Value值中的STARTKEY和ENDKEY,因为这两个值记录了该region上存储表"friend"中Row_Key的范围。因为在HBase表中,row_key是按照字典序进行排序的。所以其实HBase在对表进行切分时,就是横向切分,比如row_key范围在0~1000的划分成一个region保存到一个region server上,1001~2000的region存储在另一个region server上。所以这里的STARTKEYENDKEY就代表了当前region所包含的row_key值的范围。
    有了上面的知识就能解答HBase是如何利用元数据来完成查询请求。首先HBase根据查询请求中的表和Row_Key值,在元数据信息中进行比对,对于表划分成的每个region,HBase比较待查询的Row_Key值是否在该region保存的Row_Key范围内,也就是判断是否在STARTKEYENDKEY范围内。如果在,说明待查询的数据就保存在该region内,然后就可以通过column=info:server 这条记录找到该region所存储在哪个节点(region server)上,这样就可以去对应节点下的region上进行查询了。

通过上面的介绍就能知道,流程3)就是从元数据信息中获取到待查询的数据在哪个Region Server上的Region进行存储。

  1. 返回meta信息。此时客户端就知道要去哪个节点下进行查询。
  2. Client向对应的Region Server发送get请求,查询数据。
    这里需要介绍一下HBase上Region Server的内存分为两个部分:
    一个部分作为Menstore,主要用来写。另一个部分作为BlockCache,主要用于读数据。
    此时当读取数据时,首先是从Region Server的Block Cache缓冲中进行读取。如果BlockCache中没有找到该数据,再到StoreFile上进行读取。StoreFile就是保存在磁盘中的数据。可以想象从磁盘中读取数据肯定是比较慢的,所以从storeFile中读取到数据之后,不是直接把结果数据返回给客户端,而是把数据先写入BlockCache中,目的是为了加快后续的查询。最后才是将结果返回给客户端。

通过以上的流程,我们应该就能大体理解到HBase读数据的流程。接下来继续介绍写数据的流程。

HBase写数据流程

在这里插入图片描述

整体写流程的前面几步,跟读流程的过程基本类似。主要就是Client发送put写请求时。

5)客户端发送写请求时。首先会把数据分别写到WAL (write ahead log) 和 Memstore各一份。虽然数据写入内存速度快,但是内存大小总是有限,所以当Memstore大小达到阈值后,就需要把数据刷写到磁盘中进行保存,生成storeFile文件。因为刷写数据到磁盘的过程,会产生多个storefile文件,而此时太多的storeFile文件也会影响查询速度。所以这里就涉及到HBase的flush(刷写)和compact(合并)机制

HBase的flush(刷写)和compact(合并)机制

Flush机制
刷写触发的时机可以有几下几种:

  • 当memstore的⼤⼩超过设定值的时候,会flush到磁盘,默认为128M
  • 当memstore中的数据时间超过1⼩时,会flush到磁盘
  • HregionServer的全局memstore的⼤⼩,超过该⼤⼩会触发flflush到磁盘的操作,默认是堆⼤⼩的40%
  • ⼿动flflush

阻塞机制
以上介绍的是Store中memstore数据刷写磁盘的标准,但是Hbase中是周期性的检查是否满⾜以上标准满⾜则进⾏刷写,但是如果在下次检查到来之前,数据疯狂写⼊Memstore中,会出现什么问题呢?

会触发阻塞机制,此时⽆法写⼊数据到Memstore,数据⽆法写⼊Hbase集群

  • memstore中数据达到512MB
    计算公式:hbase.hregion.memstore.flflush.size*hbase.hregion.memstore…block.multiplier
    hbase.hregion.memstore.flflush.size刷写的阀值,默认是 134217728,即128MB。
    hbase.hregion.memstore.block.multiplier是⼀个倍数,默认 是4。

  • RegionServer全部memstore达到规定值
    hbase.regionserver.global.memstore.size.lower.limit是0.95,
    hbase.regionserver.global.memstore.size是0.4,
    堆内存总共是 16G,
    触发刷写的阈值是:6.08GB 触发阻塞的阈值是:6.4GB

Compact合并机制

  • 在hbase中主要存在两种类型的compac合并
    • minor compact ⼩合并
      在将Store中多个HFile(StoreFile)合并为⼀个HFile。
      这个过程中,删除和更新的数据仅仅只是做了标记,并没有物理移除,这种合并的触发频率很⾼。
      minor compact⽂件选择标准由以下⼏个参数共同决定:
      触发条件

      • memstore flflush
        在进⾏memstore flflush前后都会进⾏判断是否触发compact

      • 定期检查线程
        周期性检查是否需要进⾏compaction操作,由参数:hbase.server.thread.wakefrequency决定,默认值是10000 millseconds

    • major compact ⼤合并
      合并Store中所有的HFile为⼀个HFile。
      这个过程有删除标记的数据会被真正移除,同时超过单元格maxVersion的版本记录也会被删除。合并频率⽐较低,默认7天执⾏⼀次,并且性能消耗⾮常⼤,建议⽣产关闭(设置为0),在应⽤空闲时间⼿动触发。⼀般可以是⼿动控制进⾏合并,防⽌出现在业务⾼峰期。

Region拆分机制

最后,再来介绍一下Region的拆分机制。
Region中存储的是⼤量的rowkey数据 ,当Region中的数据条数过多的时候,直接影响查询效率.当Region过⼤的时候.HBase会拆分Region , 这也是Hbase的⼀个优点 .

拆分示意图:
在这里插入图片描述

拆分策略

1) HBase的Region Split策略⼀共有以下⼏种:
0.94版本前默认切分策略
当region⼤⼩⼤于某个阈值(hbase.hregion.max.filesize=10G)之后就会触发切分,⼀个region等分为2个region。
但是在⽣产线上这种切分策略却有相当⼤的弊端:切分策略对于⼤表和⼩表没有明显的区分。阈值(hbase.hregion.max.filesize)设置较⼤对⼤表⽐较友好,但是⼩表就有可能不会触发分裂,极端情况下可能就1个,这对业务来说并不是什么好事。如果设置较⼩则对⼩表友好,但⼀个⼤表就会在整个集群产⽣⼤量的region,这对于集群的管理、资源使⽤、failover来说都不是⼀件好事。

2)IncreasingToUpperBoundRegionSplitPolicy
0.94版本~2.0版本默认切分策略
切分策略稍微有点复杂,总体看和ConstantSizeRegionSplitPolicy思路相同,⼀个region⼤⼩⼤于设置阈值就会触发切分。但是这个阈值并不像
ConstantSizeRegionSplitPolicy是⼀个固定的值,⽽是会在⼀定条件下不断调整,调整规则和region所属表在当前regionserver上的region个数有关系.
region split的计算公式是:
regioncount^3 * 128M * 2,当region达到该size的时候进⾏split
例如:
第⼀次split:1^3 * 256 = 256MB
第⼆次split:2^3 * 256 = 2048MB
第三次split:3^3 * 256 = 6912MB
第四次split:4^3 * 256 = 16384MB > 10GB,因此取较⼩的值10GB
后⾯每次split的size都是10GB了

3)SteppingSplitPolicy
2.0版本默认切分策略
这种切分策略的切分阈值⼜发⽣了变化,相⽐IncreasingToUpperBoundRegionSplitPolicy 简单了⼀些,依然和待分裂region所属表在当前regionserver上的region个数有关系,如果region个数等于1,切分阈值为flush size * 2,否则为MaxRegionFileSize。这种切分策略对于⼤集群中的⼤表、⼩表会⽐IncreasingToUpperBoundRegionSplitPolicy 更加友好,⼩表不会再产⽣⼤量的⼩region,⽽是适可⽽⽌。

4)KeyPrefifixRegionSplitPolicy
根据rowKey的前缀对数据进⾏分组,这⾥是指定rowKey的前多少位作为前缀,⽐如rowKey都是16位的,指定前5位是前缀,那么前5位相同的rowKey在进⾏region split的时候会分到相同的region中。

5)DelimitedKeyPrefifixRegionSplitPolicy
保证相同前缀的数据在同⼀个region中,例如rowKey的格式为:userid_eventtype_eventid,指定的delimiter为 _ ,则split的的时候会确保userid相同的数据在同⼀个region中。

6)DisabledRegionSplitPolicy
不启⽤⾃动拆分, 需要指定⼿动拆分

HBase表的预分区(region)

为何要预分区?
当⼀个table刚被创建的时候,Hbase默认的分配⼀个region给table。也就是说这个时候,所有的读写请求都会访问到同⼀个regionServer的同⼀个region中,这个时候就达不到负载均衡的效果了,集群中的其他regionServer就可能会处于⽐较空闲的状态。解决这个问题可以⽤pre-splitting,在创建table的时候就配置好,⽣成多个region。

  • 增加数据读写效率
  • 负载均衡,防⽌数据倾斜
  • ⽅便集群容灾调度region
    每⼀个region维护着startRow与endRowKey,如果加⼊的数据符合某个region维护的rowKey范围,则该数据交给这个region维
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JermeryBesian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值