上一篇文章我们介绍了如何部署HBase以及HBase常用的命令行操作,本文我们从HBase的读写流程出发来看一下HBase的原理。关注专栏《破茧成蝶——大数据篇》,查看更多相关的内容~


目录

一、HBase的架构

二、HBase的读数据流程

三、HBase的写数据流程

四、数据flush的过程

五、数据合并(compaction)过程


一、HBase的架构

尽管在前文中我们已经说过HBase的架构了,但是为了加深印象,我们这里再唠叨一下,他的架构图如下所示:

HMaster用于管理整个HBase集群,即管理每个HRegionServer,它掌握着整个集群的元数据信息。HMaster的作用主要有:1、管理用户对Table的增、删、改、查操作;2、记录Region在哪台 HRegionServer上;3、在Region Split后,负责新Region的分配;4、新机器加入时,管理HRegionServer的负载均衡,调整Region分布;5、在HRegion Server宕机后,负责失效HRegionServer上的Regions迁移。

HRegionServer是每台机器上的一个Java进程(一台机器只有一个HRegionServer进程),用来处理客户端的读写请求,并维护着元数据信息。HRegionServer的主要作用有:1、HRegionServer主要负责响应用户I/O请求,向HDFS文件系统中读写数据,是HBase中最核心的模块。2、HRegionServer管理了很多table的分区,也就是Region。

每个HRegionServer有一个HLog(有且仅有一个)。HLog是操作日志,用来做灾难恢复的,当客户端发起一个写请求时,会先往HLog中写再往Memory Store中写。为什么要设置HLog呢?假设我们进行一个写请求,会首先写到Memory Store上,等到Memory Store到达一定容量后,才会flush到StoreFile中。但是如果在这之前宕机了,那这部分操作的数据就会丢失。为了解决这个问题,于是就有了HLog。

每个HRegionServer里面有多个HRegion,一个HRegion对应于HBase的一张表(也可能是表的一部分,因为表太大了会切分,表和HRegion的对应关系是一对多),当这张表到一定大小的时候会进行切分,切分成两个HRegion,切分出来的新的HRegion会保存到另一台机器上。每个HRegionServer里面有多个HRegion,可以理解为有多张表。每个HRegion里面有多个Store(一张表中有多个列族),一个Store对应于HBase一张表的一个列族。按照这个原理,我们在设计列族的时候,可以把经常查询的列放在同一个列族,这样可以提高效率,因为在不考虑切分的情况下,同一个列族在同一个文件里面。每个Store有一个内存级别的存储Memory Store(有且仅有一个)。当Memory Store达到一定大小或一定时间后会进行数据刷写(flush),写到磁盘中(即HFile)。每个Store有多个磁盘级别的存储StoreFile,Memory Store每刷写一次就形成一个StoreFile,HFile是StoreFile在HDFS上的存储格式。

二、HBase的读数据流程

我们根据上图来说一下HBase读数据的流程。首先我们假设meta表存放在RS1上,people表行键范围1-50的存放在RS2上,行键范围51-100的存放在RS3上。Client现在要读取people表第25行,读取流程如下:

1、客户端向Zookeeper发起请求,请求元数据所在的RegionServer,Zookeeper集群存放的是HBase meta表所在的位置。

2、Zookeeper返回给客户端元数据所在的RegionServer,即RS1。

3、客户端收到应答后去请求RS1,请求查询people表的rowkey=25数据所在位置。

4、在RS1上查询meta表可知该数据在RS2机器上,即返回给客户端rowkey所在位置(RS2)。

5、客户端收到应答后去请求RS2读数据。

6、RS2查询数据返回给客户端。查询时先去内存(MemStore)查找,因为内存是最新的数据,如果找到了就返回结果,如果没找到则去缓存(blockcache(每个HRegionServer只有一个))中查找,如果找到了就返回结果,如果还没找到就去磁盘(StoreFile)找,如果在磁盘找到了,则先将结果写入缓存(blockcache),再返回给客户端,写入缓存是为了下次查询提高效率。

这里需要注意的是,在整个读数据的过程中并没有用到HMaster,即读数据的过程与HMaster无关,所以即使HMaster挂了,也仍然可以进行读数据的操作。

三、HBase的写数据流程

同样的,我们根据上图来说一下HBase写数据的流程。同样假设meta表存放在RS1上,people表行键范围1-50的存放在RS2上,行键范围51-100的存放在RS3上。Client现在要插入数据到people表中,其中rowkey=25,具体步骤如下:

1、客户端向Zookeeper发起请求,请求元数据所在的RegionServer,Zookeeper集群存放的是HBase meta表所在的位置。

2、Zookeeper返回给客户端元数据所在的RegionServer,即RS1。

3、客户端收到应答后去请求RS1,请求查询people表rowkey=25数据所在的位置。

4、在RS1上查询meta表可知该数据在RS2机器上,即返回给客户端rowkey所在位置(RS2)。

5、客户端收到应答后去请求RS2写入数据。

6、RS2收到请求,先将数据写入HLog,再将数据写入MemStore,写入MemStore后就返回给客户端写入成功信息。此时,客户端的写流程完成了。

这里同样需要注意的是,在整个写流程中HMaster也没有参与,所以如果HMaster挂了,也是可以进行写数据的。但是,如果HMaster挂的时间长了,不会触发Region切分,表就会一直变大,这样就会导致数据倾斜。

四、数据flush的过程

首先我们来看一下在hbase-default.xml配置文件中的几个配置项:

1、hbase.hregion.memstore.flush.size:默认值:128M。当Region中任意一个MemStore的大小(压缩后的大小)达到了设定值,会触发MemStore flush。

2、hbase.regionserver.optionalcacheflushinterval:默认值:3600000。HBase定期刷新MemStore,默认周期为1小时,确保MemStore不会长时间没有持久化。为避免所有的MemStore在同一时间都进行flush,定期的flush操作有20000左右的随机延时。

3、hbase.hregion.memstore.block.multiplier:默认值:2(3.0版本是4)。当Region中所有MemStore的大小总和达到了设定值(hbase.hregion.memstore.block.multiplier * hbase.hregion.memstore.flush.size,默认2*128M = 256M),会触发MemStore flush,禁止当前Region读写。

4、hbase.regionserver.global.memstore.upperLimit:默认值:0.4。当一个RegionServer中所有MemStore的大小总和达到了设定值(hbase.regionserver.global.memstore.upperLimit * hbase_heapsize,默认 0.4 * RegionServer堆内存大小),会触发全部MemStore flush,不管MemStore有多小。而且regionserver级别的flush会阻塞客户端读写。

5、hbase.regionserver.global.memstore.lowerLimit:默认值:0.38。与hbase.regionserver.global.memstore.upperLimit类似,区别是:当一个RegionServer中所有MemStore的大小总和达到了设定值(hbase.regionserver.global.memstore.lowerLimit * hbase_heapsize,默认 0.38 * RS堆内存大小),会触发部分MemStore flush。Flush顺序是按照Region的总MemStore大小,由大到小执行,先操作MemStore最大的Region,再操作剩余中最大的Region,直至总体MemStore的内存使用量低于设定值(hbase.regionserver.global.memstore.lowerLimit * hbase_heapsize)。

6、hbase.regionserver.maxlogs:默认值:32。当一个RegionServer中HLog数量达到设定值,系统会选取最早的一个HLog对应的一个或多个Region进行flush。当增加MemStore的大小以及调整其他的MemStore的设置项时,也需要去调整HLog的配置项。否则,WAL的大小限制可能会首先被触发。因而,将利用不到其他专门为Memstore而设计的优化。需要关注的HLog配置是HLog文件大小,由参数hbase.regionserver.hlog.blocksize设置(默认512M),HLog大小达到上限,或生成一个新的HLog。通过WAL限制来触发Memstore的flush并非最佳方式,这样做可能会一次flush很多Region,尽管“写数据”是很好的分布于整个集群,进而很有可能会引发flush“大风暴”。

除此之外,用户还可以使用命令在交互界面手动触发flush:

# 对某张表进行flush
flush 'TABLENAME'# 对某个Region进行flush
flush 'REGIONNAME'

Flush是由HMaster触发的,Flush顺序是按照Memstore由大到小执行,先Flush Memstore最大的Region,再执行次大的,直至总体Memstore内存使用量低于阈值(hbase.regionserver.global.memstore.lowerLimit)。这里需要注意的是HBase的最小flush单元是HRegion而不是单个MemStore。

flush的过程大致分为三个阶段,分别是:

1、prepare阶段:遍历当前Region中的所有MemStore,将MemStore中当前数据集kvset做一个快照snapshot,然后再新建一个新的kvset,后期的所有写入操作都会写入新的kvset中。整个flush阶段读操作读MemStore的部分,会分别遍历新的kvset和snapshot。prepare阶段需要加一把updateLock对写请求阻塞,结束之后会释放该锁。因为此阶段没有任何费时操作,因此持锁时间很短。

2、flush阶段:遍历所有MemStore,将prepare阶段生成的snapshot持久化为临时文件,临时文件会统一放到目录.tmp下。这个过程因为涉及到磁盘IO操作,因此相对比较耗时。

3、commit阶段:遍历所有的MemStore,将flush阶段生成的临时文件移到指定的Column family目录下,生成对应的Storefile(HFile)和Reader,把Storefile添加到HStore的Storefiles列表中,最后再清空prepare阶段生成的snapshot。

五、数据合并(compaction)过程

由于在flush过程中,可能会产生很多小文件,而HDFS不适合存储小文件,所以在写入HDFS之前会进行合并操作。首先我们来看一下在hbase-default.xml配置文件中的几个配置项:

1、hbase.hregion.majorcompaction:一个region进行major compaction合并的周期,在这个点的时候,这个region下的所有hfile会进行合并,默认是7天,major compaction非常耗资源,建议生产关闭(设置为0),在应用空闲时间手动触发。

2、hbase.hstore.compactionThreshold:一个store里面允许存的hfile的个数,超过这个个数会被写到新的一个hfile里面也即是每个region的每个列族对应的memstore在fulsh为hfile的时候,默认情况下当超过3个hfile的时候就会对这些文件进行合并重写为一个新文件,设置个数越大可以减少触发合并的时间,但是每次合并的时间就会越长。

需要注意的是,当我们利用shell命令或者API删除数据的时候,数据并没有被删除,而是被打上标记,而是在这里的compaction合并过程中才会被完全删除。

本文到此已经接近尾声了,本文主要讲述了一下HBase的原理,内容可能比较抽象。你们在此过程中遇到了什么问题,欢迎留言,让我看看你们都遇到了哪些问题~

五十一、HBase的原理相关推荐

  1. ibe加密原理_第五十一个知识点:什么是基于ID的加密的安全模型,然后描述一个IBE方案...

    第五十一个知识点:什么是基于ID的加密的安全模型,然后描述一个IBE方案 在公钥密码学中,如果Alice想要给Bob发送一条消息,她需要Bob的公钥,一般来说公钥都很长,就像一个随机的字符串. 假设A ...

  2. 2021年大数据HBase(十四):HBase的原理及其相关的工作机制

    全网最详细的大数据HBase文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 HBase的原理及其相关的工作机制 一.HBase的flus ...

  3. Python编程基础:第五十一节 将函数赋值给变量Assign Functions to Variables

    第五十一节 将函数赋值给变量Assign Functions to Variables 前言 实践 前言 简而言之,将函数赋值给变量就是为函数重命名,定义方式为新的函数名称=旧的函数名称,重命名后的新 ...

  4. OpenCV学习笔记(五十一)——imge stitching图像拼接stitching OpenCV学习笔记(五十二)——号外:OpenCV 2.4.1 又出来了。。。。。 OpenCV学习笔记(五

    OpenCV学习笔记(五十一)--imge stitching图像拼接stitching stitching是OpenCV2.4.0一个新模块,功能是实现图像拼接,所有的相关函数都被封装在Stitch ...

  5. 频谱仪的更改ip_【正点原子FPGA连载】第五十一章 基于FFT IP核的音频频谱仪-摘自【正点原子】开拓者 FPGA 开发指南 (amobbs.com 阿莫电子论坛)...

    本帖最后由 正点原子 于 2020-10-24 15:19 编辑 203429z6c3os33t8albi33.png (66.36 KB) 2019-7-28 15:14 上传 第五十一章 基于FF ...

  6. 第五十一篇 并发编程——多进程

    目录 第五十一篇 并发编程--多进程 一.什么是进程 经典举例说明进程,以及切换 二.进程与程序 三.线程 进程和线程的关系 四.进程PID与PPID 1.PID 2.PPID 五.并发与并行,阻塞与 ...

  7. ELK系列(十五)、Elasticsearch核心原理一篇全搞定

    目录 Lucene 介绍 核心术语 如何理解倒排索引? 检索方式 分段存储 段合并策略 Elasticsearch 核心概念 节点类型 集群状态 3C和脑裂 1.共识性(Consensus) 2.并发 ...

  8. 乘法原理的例题和答案_【原创】奥数解析(五十一)加法原理和乘法原理

    五年级奥数解析(五十一)加法原理和乘法原理 <奥赛天天练>第五十一讲<加法原理和乘法原理>,进一步学习运用加法原理和乘法原理解答比较复杂的计数问题.有关加法原理和乘法原理的简要 ...

  9. HBase Region原理总结归纳

    HBase Region原理总结 1. 环境准备 基于Hadoop 3.2.1 基于zookeeper 3.4.6 基于Hbase 2.2.5 资料来源: 官网http://hbase.apache. ...

最新文章

  1. SAP RETAIL 特性树(Characteristic Tree)的定义
  2. [CoolStuff]有趣的Zumobi
  3. Android 自定义ProgressDialog
  4. 开源项目成熟度分析工具-利用github api获取代码库的信息
  5. [tomcat]-tomcat8启动时SessionIdGeneratorBase.createSecureRandom耗时
  6. linux下的struct sigaction
  7. halcon reduce_ocr_class_svm 缩减基于SVM的OCR分类器。
  8. 神经网络与深度学习——TensorFlow2.0实战(笔记)(四)(python函数)
  9. 构建实时数据仓库首选,云原生数据仓库技术解密
  10. Android应用开发以及设计思想深度剖析(2)
  11. ofd阅读器qt_OFD编辑器实例
  12. 如何用谷歌地图下载器下载大字体谷歌地图打印喷绘
  13. opencv 查找白色图片的一个黑点
  14. SPADE 代码略解 ade20k数据集
  15. 如何减小电压跟随器输出电阻_逐次比较式模数转换器如何获取最佳采样频率
  16. Win10系统此电脑隐藏特定文件夹
  17. ECshop生成网站地图url
  18. 【昊泽爷爷】六一儿童节礼物——学做简单机器人的工作台
  19. Yolov5进阶之一摄像头实时采集识别
  20. 【JY】知名显式动力学求解器Radioss宣布开源

热门文章

  1. TCP / IP协议 --- 计算机层面
  2. 腾讯T13技术大佬被裁:曾两次「惊动」马化腾,现年47厂龄16年
  3. 公司监事要承担哪些责任及义务
  4. 找素数的几种简单方法
  5. 城市大脑智慧交通小脑建设赋能城市交通服务
  6. ElasticSearch分布式搜索框架
  7. 微信小程序bug总结
  8. Android Animation动画原理源码分析
  9. 图解CSS伪类和伪元素
  10. 三级数据库全真模拟试题(一)