五十一、HBase的原理
上一篇文章我们介绍了如何部署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的原理相关推荐
- ibe加密原理_第五十一个知识点:什么是基于ID的加密的安全模型,然后描述一个IBE方案...
第五十一个知识点:什么是基于ID的加密的安全模型,然后描述一个IBE方案 在公钥密码学中,如果Alice想要给Bob发送一条消息,她需要Bob的公钥,一般来说公钥都很长,就像一个随机的字符串. 假设A ...
- 2021年大数据HBase(十四):HBase的原理及其相关的工作机制
全网最详细的大数据HBase文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 HBase的原理及其相关的工作机制 一.HBase的flus ...
- Python编程基础:第五十一节 将函数赋值给变量Assign Functions to Variables
第五十一节 将函数赋值给变量Assign Functions to Variables 前言 实践 前言 简而言之,将函数赋值给变量就是为函数重命名,定义方式为新的函数名称=旧的函数名称,重命名后的新 ...
- OpenCV学习笔记(五十一)——imge stitching图像拼接stitching OpenCV学习笔记(五十二)——号外:OpenCV 2.4.1 又出来了。。。。。 OpenCV学习笔记(五
OpenCV学习笔记(五十一)--imge stitching图像拼接stitching stitching是OpenCV2.4.0一个新模块,功能是实现图像拼接,所有的相关函数都被封装在Stitch ...
- 频谱仪的更改ip_【正点原子FPGA连载】第五十一章 基于FFT IP核的音频频谱仪-摘自【正点原子】开拓者 FPGA 开发指南 (amobbs.com 阿莫电子论坛)...
本帖最后由 正点原子 于 2020-10-24 15:19 编辑 203429z6c3os33t8albi33.png (66.36 KB) 2019-7-28 15:14 上传 第五十一章 基于FF ...
- 第五十一篇 并发编程——多进程
目录 第五十一篇 并发编程--多进程 一.什么是进程 经典举例说明进程,以及切换 二.进程与程序 三.线程 进程和线程的关系 四.进程PID与PPID 1.PID 2.PPID 五.并发与并行,阻塞与 ...
- ELK系列(十五)、Elasticsearch核心原理一篇全搞定
目录 Lucene 介绍 核心术语 如何理解倒排索引? 检索方式 分段存储 段合并策略 Elasticsearch 核心概念 节点类型 集群状态 3C和脑裂 1.共识性(Consensus) 2.并发 ...
- 乘法原理的例题和答案_【原创】奥数解析(五十一)加法原理和乘法原理
五年级奥数解析(五十一)加法原理和乘法原理 <奥赛天天练>第五十一讲<加法原理和乘法原理>,进一步学习运用加法原理和乘法原理解答比较复杂的计数问题.有关加法原理和乘法原理的简要 ...
- HBase Region原理总结归纳
HBase Region原理总结 1. 环境准备 基于Hadoop 3.2.1 基于zookeeper 3.4.6 基于Hbase 2.2.5 资料来源: 官网http://hbase.apache. ...
最新文章
- SAP RETAIL 特性树(Characteristic Tree)的定义
- [CoolStuff]有趣的Zumobi
- Android 自定义ProgressDialog
- 开源项目成熟度分析工具-利用github api获取代码库的信息
- [tomcat]-tomcat8启动时SessionIdGeneratorBase.createSecureRandom耗时
- linux下的struct sigaction
- halcon reduce_ocr_class_svm 缩减基于SVM的OCR分类器。
- 神经网络与深度学习——TensorFlow2.0实战(笔记)(四)(python函数)
- 构建实时数据仓库首选,云原生数据仓库技术解密
- Android应用开发以及设计思想深度剖析(2)
- ofd阅读器qt_OFD编辑器实例
- 如何用谷歌地图下载器下载大字体谷歌地图打印喷绘
- opencv 查找白色图片的一个黑点
- SPADE 代码略解 ade20k数据集
- 如何减小电压跟随器输出电阻_逐次比较式模数转换器如何获取最佳采样频率
- Win10系统此电脑隐藏特定文件夹
- ECshop生成网站地图url
- 【昊泽爷爷】六一儿童节礼物——学做简单机器人的工作台
- Yolov5进阶之一摄像头实时采集识别
- 【JY】知名显式动力学求解器Radioss宣布开源