HBase 之三 HBase 的读写流程

前言

​ 上一篇详细讲述了 HBase 的数据模型以及组织架构,这一篇就来讲讲 HBase 的读写流程,由于其依托于 Zookeeper 与 HDFS 因此其读写流程较为复杂,推荐先阅读HBase的数据模型与架构熟悉 HBase 的组织架构,然后再阅读本文会有更好的理解,如果文中有不正确的地方欢迎指出,一同进步!

HBase 写流程

​ 相比于读流程写流程更加复杂一些,因此我们先来讲解写流程。

HBase 写流程总览

​ 话不多说直接上图,HBase 总体写流程如下:

在这里插入图片描述

​ 从图上可以看到当我们通过 Client 访问 HBase 并向其中写入数据会经过以下步骤:

  1. Client 会首先访问 Zookeeper 来获取 meta data(元数据) 所在的服务器(注意是 meta data 所在的服务器而不是 meta data), 还记得上一篇所说的 zookeeper 的作用吗,其中有一个就是作为 HBase 集群的统一元数据入口,因此访问 HBase 集群的第一步是先访问 Zookeeper,具体的节点信息已经写在图上了
  2. Zookeeper 将 meta-region-server (meta data 所在服务器) 返回给 Cilent
  3. Client 根据 Zookeeper 返回的信息访问 meta-region-server 并请求 meta data
  4. meta-region-server 返回 meta data (对应 HBase 中的 hbase:meta 表) 给 Client,Client 根据 namespace:table/rowKey 查询 meta data 并得到应该访问那台 HRegionServer 的那个 Region,同时 Client 会将 meta data 和 要访问的表信息缓存在本地的 meta cache 中以便后续的操作与访问
  5. Client 将数据顺序写入目标 HRegionServer 的 HLog 文件
  6. Client 将数据写入目标 Region 的 MemStore 中,注意这里是先写 HLog 再写 MemStore,这样做的目的是为了保证数据不丢失 (类似于 HDFS 写入时 先写 editlog 再写数据),同时写入 HLog 和 MenStore 的操作都是原子操作即如果失败则数据全部回退。
  7. 当 HLog 和 MenStore 都写入完成后会发送 ACK 确认
  8. 当满足一定条件时 MemStore 会将数据刷写到 HFile 中

上面步骤中 5. 和 6. 在实际的 Hbase 中有一些不同,在实际的 Hbase 中也是先写 Hlog 再写 MemStore,但实际上写的是 Client 本地的 Hlog,其更细节的顺序应该为:

  1. Client 在本地写一份 WAL(HLog) 来记录操作过程及数据,但不将其同步到 HDFS 集群

  2. 将数据写入 Hbase 集群上目标 region 中的 MemStore 中

  3. 将本地 WAL 追加到目标 HRegionServer 的 WAL 中,如果在追加过程中出错则回退 HDFS 上的 WAL 并将 MemStore 数据一并回退。

    具体的可以参考 HRegion 类中的 doMiniBatchMutation() 方法,其中有详细的注释。

MemStore Flush

​ 在上一节 HBase 写流程的最后有提到当 MemStore 达到一定条件后会将数据刷写到 HFile 保存起来,这一节就来讲讲 Flush 相关的内容。

​ 具体来说有以下这些情况会出发 MemStore Flush:

  1. 单个 Region 内的所有 MemStore 占用内存总和超过一定的阈值
  2. 整个 HRegionServer 中的所有 MemStore 占用内存总和超过一定阈值
  3. WAL 的数量超过一定阈值
  4. 定期自动刷写
  5. 更新数量超过一定阈值
  6. 手动刷写
单个 Region 内的所有 MemStore 占用内存总和超过一定的阈值

​ 当单个 MemStore 的大小达到了 hbase.hregion.memstore.flush.size(默认为 128M) ,其所在 Region 的所有 MemStore 都会将数据刷写成 HFile。
​ 当我们的数据增长非常快短时间内单个 Region 内 MemStore 占用内存总和达到了 hbase.hregion.memstore.flush.size(默认为 128M) * hbase.hregion.memstore.block.multiplier(默认为 4),即占用内存总量达到 512M,除了会触发全部 MemStore 的刷写外,Region 还会阻塞外部对于此 Region 的写请求,此时如果往对应 Region 写数据会发生RegionTooBusyException 异常,这种情况下就会影响 HBase 的性能因此在实际应用中需要根据具体的场景来调整参数避免 Region 写阻塞的发生。

整个 HRegionServer 中的所有 MemStore 占用内存总和超过一定阈值

​ 对于整个 HRegionServer 而言 Hbase 默认会分配给其 40% 的 JVM 内存作为 MemStore 的内存java_heapsize*hbase.regionserver.global.memstore.size(默认值 0.4),当整个 HRegionServer 中 MemStore 占用的内存数量达到 java_heapsize*hbase.regionserver.global.memstore.size(默认值 0.4)*hbase.regionserver.global.memstore.size.lower.limit(默认值 0.95) 即 95% 的分配内存时 HRegionServer 会将 MemStore 从小到达刷写成 HFile,并且期间会阻塞整个 HRegionServer 的写请求,这种情况是可能长达数分钟是非常严重的问题,因此应该极力避免这种情况的发生。

WAL 的数量超过一定阈值

​ 当 WAL 的数量超过 hbase.regionserver.maxlogs设置的值就会将 WAL 按照时间顺序进行刷写,如果未设置hbase.regionserver.maxlogs参数则按照 max(32, hbase_heapsize * hbase.regionserver.global.memstore.size * 2 / logRollSize)来计算 WAL 的数量。

定期自动刷写

​ 经过hbase.regionserver.optionalcacheflushinterval(默认1小时) 所设定的时间会自动出发 MemStore 的刷写

更新数量超过一定阈值

​ 如果 HBase 的某个 Region 更新的很频繁,而且既没有达到自动刷写阀值,也没有达到内存的使用限制,但是内存中的更新数量已经足够多,比如超过 hbase.regionserver.flush.per.changes 参数配置,默认为30000000,那么也是会触发刷写的。

手动触发刷写

​ 可调用 HBase 的 API 手动刷写数据

// 用 Admin 对象调用 flush 方法
admin.flush();
admin.flushRegion();

根据上面的一些介绍可以发现关于 MemStore 的刷写相关设置需要仔细考虑,一旦发生 HRegionServer 等级的刷写将会导致整个集群性能的下降,MemStore 是 Hbase 中非常关键的一个组件有关其的更多内容可以查看 HBase 入门之数据刷写(Memstore Flush)详细说明深入理解HBase的memestore、storeFile(HFile)这两篇博文。

HBase 读流程

​ 讲完了 Hbase 的写流程接下来我们来讲一下 Hbase 的读流程,总览图如下:

在这里插入图片描述

​ 从上图可以看到获取元数据方面,读流程中和写流程是一样的不再赘述,我们具体来看看图中第五步读取数据这里。

​ 从上图可以看到,Client 在从 HRegionServer 读取数据的过程是 Block cache,MemStore,StoreFile。其中 Block cache 称之为读缓存,每次读取数据都会先去 Block cache 中寻找如果没有找到那么会去 MemStore 中寻找,去到 MemStore 寻找的理由是基于这样一个事实新写入的数据大概率会被马上查询,如果 MemStore 也没有找到数据那么会到 StoreFile 中读取,当然前述流程是单版本的情况,在 Hbase 中可以通过 timestamp 来指定同一 rowkey 数据的多个版本,因此在多版本的情况下会讲这三个地方读取的数据 merge 起来一同返回给 Client。需要注意的是在每次读取完数据后都会将读取的数据放入 Block cache,以便后续的访问读取,Block cache 中也有非常多的细节本文在此不再赘述详细可查阅这篇博文HBase BlockCache系列 – 走进BlockCache

结语

​ 有关 HBase 的读写流程本篇就写到这里,其中 MemStore 的刷写尤为关键其一定程度上影响了 Hbase 的整体性能,因此在实际场景下考虑其相关参数是非常重要的,下一篇讲一下 Region Split 和 StoreFile Compaction 这俩个操作前者解决了 region 过大的问题,后者解决了小文件过多的问题,同样也是 Hbase 中非常关键的特性。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值