1首次读写流程图

2 首次写基本流程

(1)客户端发起PUT请求,Zookeeper返回hbase:meta所在的region server

(2)去(1)返回的server上,根据rowkey去hbase:meta中获取即将进行写操作的region server,并将相关的信进行本地缓存

(3)客户端把put请求发送到(2)返回的HRegion server上,根据HRegion server的架构图,细化如下:

    • 首先写入WAL(写入到磁盘文件中)

    • 根据Rowkey获取HRegion, 根据column获取HStore
    • 将数据写入HStore的MemStore

    • 持续写入MemStore时,如果MemStore满了,将其加入到Flush队列,由单独的线程flush到磁盘上,形成Storefile

注:客户端进行后续读写时, 首先查询本地缓存获取meta表的位置。

3 flush时机(触发条件)

  • MemStore级别限制

Region中任意一个MemStore的大小超过上限(hbase.hregion.memstore.flush.size,默认128MB),会触发MemStore刷新

  • HRegion 级别限制

当Region中所有的MemStore的总和大小超过上限(hbase.hregion.memstore.block.multiplier * hbase.hregion.memstore.flush.size,默认 2* 128M = 256M),会触发MemStore刷新

  • HRegion Server级别限制

当一个Regoin server中的所有MemStore的总和大小超过上限(hbase.regionserver.global.memstore.upperLimit * hbase_heapsize,默认40%的JVM内存使用量)回触发部分MemStore刷新。刷新的顺序是按照MemStore的大小排序,先刷新最大的MemStore所在的Region,再刷新次大的,直至总体Memstore内存使用量低于阈值(hbase.regionserver.global.memstore.lowerLimit * hbase_heapsize,默认38%的JVM内存使用量)。

  • HRegion Server log限制

当一个Region Server中HLog数量达到上限(可通过参数hbase.regionserver.maxlogs配置)时,系统会选取最早的一个 HLog对应的一个或多个Region进行flush

  • MemStore 定时flush

默认周期为1小时,确保Memstore不会长时间没有持久化。为避免所有的MemStore在同一时间都进行flush导致的问题,定期的flush操作有20000左右的随机延时。

  • client手动flush

用户可以通过shell命令 flush ‘tablename’或者flush ‘region name’分别对一个表或者一个Region进行flush。

   注意MemStore进行flush的最小单位是HRegion 而不是MemStore,因此在设计中要用尽量少的family column。 因为Column Family个数跟HStore个数对应,如果有多个Column Family就会有多个HStore,其中一个HStore的MemStore满了导致flush时,由于flush的最小单元是HRegion,会导致HRegion中的多有的MemStore都flush成文件。而且还有个问题,有的column family可能很多行数据了,但是有的可能就几条也flush出来,带来性能问题。而且因为HBase是按行的方向上分成几个region,可能导致这几条也要被分成几个region,分不到不同的文件里。

问题:为什么不以MemStore为单位进行flush呢?

解答:如果仅选择MemStore较大的进行Flush,那么HLog中记录的Key在同一个region的不同colomn family(Store)上就会有不同的key区间(难道目前HLog只细化到rowkey级别?待考证) 而且进行scan操作时就不统一了(参考http://blog.csdn.net/liyanyun/article/details/20134417)(个人认为这不是问题:以为scan的结果肯定是MemStore和HFile结果的总和,所以不管有没有被flush出来,都能获取到结果,待考证

另:MemStore每次进行flush操作都会产生新的HFile,而不是修改现有的文件(参见http://www.cnblogs.com/tgzhu/p/5859014.html)

memstoreFlush出来的文件是经过压缩的,比如memstoreFlushSize设置为640M,真正flush出来的storefile的大小可能是50M左右,没错,压缩比例就是这么大。

4 flush流程

为了减少flush过程对读写的影响,HBase采用了类似于两阶段提交的方式,将整个flush过程分为三个阶段:

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

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

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

5. Flush对读写的影响

大部分Memstore Flush操作都不会对业务读写产生太大影响,比如这几种场景:HBase定期刷新Memstore、手动执行flush操作、触发Memstore级别限制、触发HLog数量限制以及触发Region级别限制等,这几种场景只会阻塞对应Region上的写请求,阻塞时间很短,毫秒级别。

然而一旦触发Region Server级别限制导致flush,就会对用户请求产生较大的影响。会阻塞所有落在该Region Server上的更新操作,阻塞时间很长,甚至可以达到分钟级别。一般情况下Region Server级别限制很难触发,但在一些极端情况下也不排除有触发的可能。

参考文献:https://mapr.com/blog/in-depth-look-hbase-architecture/

http://hbasefly.com/2016/03/23/hbase-memstore-flush/

HBase写过程详解的更多相关文章

  1. HBase 协处理器编程详解,第二部分:客户端代码编写

    实现 Client 端代码 HBase 提供了客户端 Java 包 org.apache.hadoop.hbase.client.coprocessor.它提供以下三种方法来调用协处理器提供的服务: ...

  2. Hadoop MapReduce执行过程详解(带hadoop例子)

    https://my.oschina.net/itblog/blog/275294 摘要: 本文通过一个例子,详细介绍Hadoop 的 MapReduce过程. 分析MapReduce执行过程 Map ...

  3. Hadoop Mapreduce分区、分组、二次排序过程详解[转]

    原文地址:Hadoop Mapreduce分区.分组.二次排序过程详解[转]作者: 徐海蛟 教学用途 1.MapReduce中数据流动   (1)最简单的过程:  map - reduce   (2) ...

  4. cocos2dx-3.x 导出自定义类到 lua 过程详解

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.简介 最近正在学习cocos2d中的lua游戏开发,因为lua开发的热更新特性,大家开发游戏好像都会优先选择lua作为 ...

  5. MySQL关闭过程详解和安全关闭MySQL的方法

    MySQL关闭过程详解和安全关闭MySQL的方法 www.hongkevip.com 时间: -- : 阅读: 整理: 红客VIP 分享到: 红客VIP(http://www.hongkevip.co ...

  6. 转载:C/C++源代码到可执行程序的过程详解

    C/C++源代码到可执行程序的过程详解 编译,编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格 ...

  7. Hadoop学习之Mapreduce执行过程详解

    一.MapReduce执行过程 MapReduce运行时,首先通过Map读取HDFS中的数据,然后经过拆分,将每个文件中的每行数据分拆成键值对,最后输出作为Reduce的输入,大体执行流程如下图所示: ...

  8. Android的init过程详解(一)

    Android的init过程详解(一) Android的init过程(二):初始化语言(init.rc)解析 本文使用的软件版本 Android:4.2.2 Linux内核:3.1.10 本文及后续几 ...

  9. 【STM32H7教程】第13章 STM32H7启动过程详解

    完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第13章       STM32H7启动过程详解 本章教 ...

随机推荐

  1. mysql 语句的查询过程解析

    select * from tb where ID = 1 下面解析的查询过程都是基于上面的简单查询,该系列的所有素材都来自于丁奇的mysql的45讲 1.建立连接 a.客户端发出请求,请求首先到达连 ...

  2. Libevent:5events相关

    Libevents的基本操作单元是event,每一个event代表了一些条件的集合,这些条件包括: 文件描述符已经准备好读或写 文件描述符正在变为就绪,准备好读或写(仅限于边沿触发) 超时事件 信号发 ...

  3. GIAC2019 演讲精选 | 面向未来的黑科技——UI2CODE闲鱼基于图片生成跨端代码

    一直以来, 如何从‘视觉稿’精确的还原出 对应的UI侧代码 一直是端侧开发同学工作里消耗比较大的部分,一方面这部分的工作 比较确定缺少技术深度,另一方面视觉设计师也需要投入大量的走查时间,有大量无谓的 ...

  4. 基于opencv的RandomForest随机森林

    2.OpenCV函数使用 OpenCV提供了随机森林的相关类和函数.具体使用方法如下: (1)首先利用CvRTParams定义自己的参数,其格式如下 CvRTParams::CvRTParams(in ...

  5. python 布尔型(bool)

  6. CSS检测窗口大小显示和隐藏内容

    代码不多 用css写的话简单一点 @media (max-width: 1024px) { #hidden { display: none; } } max-width 是要检测的宽度

  7. ubuntu18.04 挂载ntfs硬盘无法写入解决办法

    win10和ubuntu18.04双系统,在ubuntu下通过/etc/fstab挂载ntfs硬盘无写入权限,尝试通过chmod修改写入权限和ntfs-config图形工具修改写入权限均失败.在ubu ...

  8. 创建JAVASCRIPT对象3种方法

    创建JAVASCRIPT对象3种方法 方法一:直接定义并创建对象实例 var obj = new Object();    //创建对象实例 //添加属性obj.num = 5;   //添加属性 o ...

  9. javascript 变量的提升

    下面是一个关于全局和局部作用域的问题 var a = 123; function f(){ alert(a); var a = 1; alert(a); } f(); 大家第一眼看到后都会认为第一次a ...

  10. TabHost选项卡的实现(二):使用Fragment实现

    在上一篇博客<TabHost选项卡的实现(一):使用TabActivity实现>中,讲解了如何使用TabActivity创建管理选项卡,但是,通过TabActivity创建选项卡的方式已经 ...