如何像海豚一样在数据海洋里遨游?|Hbase数据处理流程详解

写在前面:我是「且听风吟」,目前是某上市游戏公司的大数据开发工程师,热爱大数据开源技术,喜欢分享自己的所学所悟,现阶段正在从头梳理大数据体系的知识,以后将会把时间重点放在Spark和Flink上面。

如果你也对大数据感兴趣,希望在这个行业一展拳脚。欢迎关注我,我们一起学习。博客地址:https://ropledata.blog.csdn.net

博客的名字来源于:且听风吟,静待花开。也符合我对技术的看法,想要真正掌握一门技术就需要厚积薄发的毅力,同时保持乐观的心态。

你只管努力,剩下的交给时间!

图片

一、前言

Hbase作为咱们大数据生态里必不可少的一环,它的重要性不言而喻。官方对它的解释是Hbase是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,在极易扩展的前提下,它还适合存储PB级别的海量数据,并且能在几十到百毫秒内返回数据。

Hbase的logo是海豚的形象,寓意在大数据的海洋里穿梭遨游。事实上数据的处理流程一直都是Hbase的核心知识点,下面就让我们一起乘风破浪,解决Hbase的数据读写流程、数据flush流程和数据合并流程。

二、数据写流程

Hbase写流程
首先介绍数据的写入流程,大致流程如上图所示,下面进行分步骤分析:

  1. 首先会从zookerper里找到meta表的region的位置并读取meta表中的数据。
  2. 由于meta表里存储了用户表的region信息,所以会根据namespace、表名和rowkey在meta表中的数据里找到写入数据对应的region信息。
  3. 根据上一步拿到的region信息找到它对应的regionserver,然后就可以写入数据了。
  4. 其实写数据会把数据分别写到Hlog和memstore各一份。(写入Hlog是为了便于数据的持久化和恢复,写入memstore是为了查询)
  5. 然后Regionserver会向Client反馈写数据成功。

注意:在向memstore写入数据的过程中,会涉及到数据flush和数据合并过程,这一块咱们放到后面单独解释。

三、数据读流程

数据读流程
Hbase的数据读取流程大致就像上图这样,下面我们将它细化分步骤解读:

  1. 首先Client先访问zookeeper集群,从zookeeper的meta表(存储元数据)读取region的位置和meta表中的数据。(meta表中存储了用户表的region信息
  2. 我们知道meta表里存储了用户表的region信息,我们需要拿到这些信息,因此第二步Hbase会根据namespace、表名和rowkey在meta表中找到相对应的region信息。
  3. 根据上一步拿到的region信息找到它对应的regionserver,并查找这个region来读取数据。
  4. 读取数据的时候会先从MemStore找数据,如果没有,再到BlockCache里面读;BlockCache还没有,再到StoreFile上读。

我们知道Hbase中的数据是有序的,并且还有底层索引支持,所以整体的查询速度非常快。

注意:如果是从StoreFile里面读取的数据,读取完不会直接返回给客户端,而是先写入BlockCache,再返回给客户端。

四、数据flush流程

flush是Hbase的一个重要操作,其实很多情况下都会触发Flush操作,咱们把这些情况列举如下:

  1. 最常见的是Region 中所有 MemStore 占用的内存超过相关阈值;

  2. 整个 RegionServer 的 MemStore 占用内存总和大于相关阈值;

  3. WAL数量大于相关阈值;

  4. 定期自动刷写或手动触发刷写;

  5. 数据更新超过一定阈值。

以第一种情况为例,当某个 Region 中所有 MemStore 占用的内存(包括 OnHeap + OffHeap)大小超过刷写阈值的时候会触发一次刷写,这个阈值由 hbase.hregion.memstore.flush.size 参数控制,默认是128M,老版本是64M。

其实我们每次调用 put、delete 等操作时Hbase底层都会检查这个条件。数据的flush操作比较复杂,我们把数据flush简单概括为三步,了解这些就足够了:

  1. 第一步将数据刷到硬盘,将内存中的数据删除,同时删除HLog中的历史数据;
  2. 第二步将数据存储到HDFS中;
  3. 最后一步在HLog中做标记点。

五、数据合并流程

经过上面的flush操作之后,memstore里的数据会存储为Hfile(其实就是StoreFile),随着次数的增多和数据的增大,HDFS上面会出现非常多的Hfile文件,通过上面的分析,我们已经知道读数据操作会对Hfile文件进行归并查询,因此大量的Hfile文件会严重影响读数据的性能,而且这样对DataNode的影响也比较大。

那Hbase怎么解决这个问题呢?

Hbase会对Hfile文件进行compact操作,也就是这里要介绍的合并操作。合并操作会产生大量的IO,因此合并是利用IO操作换取后续读写的性能,可以说是前人栽树,后人乘凉的模式。

数据的合并又分为小合并和大合并:

  1. 小合并(minor compaction):小合并时会选择周围相邻的一些小的Hfile文件,来形成一个大一点的Hfile文件。(注意:小合并不会进行过期数据的清除。)
  2. 大合并(major compaction):大合并会把所有的Hfile文件合并成一个大的Hfile文件。(注意:大合并会删除过期数据,超出版本号的旧版本数据和delete标记的数据)

实际场景下,大合并更多的是手动进行的,因此我们通常把参数hbase.hregion.majorcompaction的值设为0,表示禁用major compaction。(默认值为7天,允许上下浮动hbase.hregion.majorcompaction * hbase.hregion.majorcompaction.jitter的值,后者默认是0.5。即[7 - 70.5, 7 + 70.5])

什么情况下会触发数据合并操作呢?

在flush操作之后,会对当前Store的文件数量进行判断,如果大于hbase.hstore.compaction.min(旧版本是hbase.hstore.compactionThreshold)的值(默认是3),就会触发数据合并操作。实际场景下这个参数默认值太小了,一般需要调大。一次minor cmpaction最多合并hbase.hstore.compaction.max个文件(默认值10)。

那数据合并的具体情况是怎样的呢?

  1. 第一步:Hmaster触发合并操作后,Region将数据块加载到本地,便于进行合并;
  2. 第二步:当合并的数据超过256M,进行拆分,将拆分后的Region分配给不同的HregionServer管理;
  3. 最后:当HregionServer宕机后,将HregionServer上的hlog拆分(注意:HLog会同步到HDFS。),然后分配给不同的HregionServer加载,并会修改.META文件。

六、总结

本文对Hbase的数据处理流程根据重点进行了详细或概括性的分析,掌握了这部分内容之后,我们就可以反过来更深入的理解Hbase的架构设计以及数据结构设计了,而且本身这部分内容对于Hbase也是非常重要的,不知道各位掌握了没有呢?

如果您对我的文章感兴趣,欢迎关注点赞,如果您有疑惑或发现文中有不对的地方,还请不吝赐教,非常感谢!!

发布了117 篇原创文章 · 获赞 431 · 访问量 27万+

猜你喜欢

转载自blog.csdn.net/qq_26803795/article/details/105797099