HBase – Memstore Flush和flush shell操作 深度解析

//memstore flush机制 和flush shell命令刷新
//Memstore是HBase框架中非常重要的组成部分之一,是HBase能够实现高性能随机读写至关重要的一环。深入理解Memstore的工作原理、运行机制以及相关配置,对hbase集群管理、性能调优都有着非常重要的帮助。

写机制(大约)
1、HBase是基于LSM-Tree模型的,
2、所有的数据更新插入操作都首先写入Memstore中(同时会顺序写到日志HLog中),
3、达到指定大小之后再将这些修改操作批量写入磁盘,生成一个新的HFile文件,这种设计可以极大地提升HBase的写入性能;
4、HBase为了方便按照RowKey进行检索,要求HFile中数据都按照RowKey进行排序,
5、Memstore数据在flush为HFile之前会进行一次排序,将数据有序化;

读机制(大约)
1、根据局部性原理,新写入的数据会更大概率被读取,
2、因此HBase在读取数据的时候首先检查请求的数据是否在Memstore,
3、写缓存未命中的话再到读缓存中查找,读缓存还未命中才会到HFile文件中查找,最终返回merged的一个结果给用户。

//可见,Memstore无论是对HBase的写入性能还是读取性能都至关重要。其中flush操作又是Memstore最核心的操作。

问题:
接下来重点针对Memstore的flush操作进行深入地解析:
1、首先分析HBase在哪些场景下会触发flush,
2、然后结合源代码分析整个flush的操作流程。
3、最后再重点整理总结和flush相关的配置参数,这些参数对于性能调优、问题定位都非常重要。

HBase会在如下几种情况下触发flush操作?
//提示:
需要注意的是MemStore的最小flush单元是HRegion而不是单个MemStore。 //这就话可以理解Wie:
当一个region是2个列族的时候,就会有2个memstore 比如如果其中一个menstore=128M了,另一个没有达到128M 不会flush
只有当region中的2个memstore都达到了128M的时候,才会触发真正的刷新region级别的flush
可想而知,如果一个HRegion中Memstore过多,每次flush的开销必然会很大,因此我们也建议在进行表设计的时候尽量减少ColumnFamily的个数。建议列族为1-3个,热门业务的列族就设计成1个
1、Memstore级别限制:当Region中任意一个MemStore的大小达到了上限(hbase.hregion.memstore.flush.size,默认128MB),会触发Memstore刷新。
2、Region级别限制:当Region中所有Memstore的大小总和达到了上限(hbase.hregion.memstore.block.multiplier hbase.hregion.memstore.flush.size,默认 2 128M = 256M),会触发memstore刷新。
3、Region Server级别限制:当一个Region Server中所有Memstore的大小总和达到了上限 (hbase.regionserver.global.memstore.upperLimit * hbase_heapsize,默认 40%的JVM内存使用量),会触发部分Memstore刷新。Flush顺序是按照Memstore由大到小执行,先Flush Memstore最大的Region,再执行次大的,直至总体Memstore内存使用量低于阈值(hbase.regionserver.global.memstore.lowerLimit * hbase_heapsize,默认 38%的JVM内存使用量)。
//影响很大
4、当一个Region Server中HLog数量达到上限(可通过参数hbase.regionserver.maxlogs配置)时,系统会选取最早的一个 HLog对应的一个或多个Region进行flush
5、HBase定期刷新Memstore:默认周期为1小时,确保Memstore不会长时间没有持久化。为避免所有的MemStore在同一时间都进行flush导致的问题,定期的flush操作有20000左右的随机延时。
6、手动执行flush:用户可以通过shell命令 flush ‘tablename’或者flush ‘region name’分别对一个表或者一个Region进行flush。
//6种方式可以触发 flush的操作,以上参数在cdh中都有

Memstore Flush流程 //具体见博客
为了减少flush过程对读写的影响,HBase采用了类似于两阶段提交的方式,将整个flush过程分为三个阶段:
1、prepare阶段
(1)遍历当前Region中的所有Memstore,将Memstore中当前数据集kvset做一个快照snapshot,然后再新建一个新的kvset。
(2)后期的所有写入操作都会写入新的kvset中,而整个flush阶段读操作会首先分别遍历kvset和snapshot,如果查找不到再会到HFile中查找。
(3)prepare阶段需要加一把updateLock对写请求阻塞,结束之后会释放该锁。
(4)因为此阶段没有任何费时操作,因此持锁时间很短
2、flush阶段
(1)遍历所有Memstore,将prepare阶段生成的snapshot持久化为临时文件,临时文件会统一放到目录.tmp下。
(2)这个过程因为涉及到磁盘IO操作,因此相对比较耗时。
3、commit阶段
(1)遍历所有的Memstore,将flush阶段生成的临时文件移到指定的ColumnFamily目录下,
(2)针对HFile生成对应的storefile和Reader,把storefile添加到HStore的storefiles列表中,
(3)最后再清空prepare阶段生成的snapshot。

Memstore Flush对业务读写的影响
1、想必对于HBase用户来说,最关心的是flush行为会对读写请求造成哪些影响以及如何避免。
2、因为不同触发方式下的flush操作对用户请求影响不尽相同,因此下面会根据flush的不同触发方式分别进行总结,并且会根据影响大小进行归类:
(1)影响甚微
正常情况下,大部分Memstore Flush操作都不会对业务读写产生太大影响,比如这几种场景:HBase定期刷新Memstore、手动执行flush操作、触发Memstore级别限制、触发HLog数量限制以及触发Region级别限制等,这几种场景只会阻塞对应Region上的写请求,阻塞时间很短,毫秒级别。

(2)影响较大
然而一旦触发Region Server级别限制导致flush,就会对用户请求产生较大的影响。会阻塞所有落在该Region Server上的更新操作,阻塞时间很长,甚至可以达到分钟级别。一般情况下Region Server级别限制很难触发,但在一些极端情况下也不排除有触发的可能,下面分析一种可能触发这种flush操作的场景:
//
相关JVM配置以及HBase配置:

maxHeap = 71
hbase.regionserver.global.memstore.upperLimit = 0.35
hbase.regionserver.global.memstore.lowerLimit = 0.30

基于上述配置,可以得到触发Region Server级别的总Memstore内存和为24.9G,如下所示:

2015-10-12 13:05:16,232 INFO [regionserver60020] regionserver.MemStoreFlusher: globalMemStoreLimit=24.9 G, globalMemStoreLimitLowMark=21.3 G, maxHeap=71 G
//根据上面第3条件的设置
710.30~710.35 //就是region server当memstore的内存综合趋于 21.3 24.85 高于24.85 就触发flush 要低于 21.3

分析:
假设每个Memstore大小为默认128M,在上述配置下如果每个Region有两个Memstore,整个Region Server上运行了100个region,根据计算可得总消耗内存 = 128M 100 2 = 25.6G > 24.9G,很显然,这种情况下就会触发Region Server级别限制,对用户影响相当大。

小结:
1、根据上面的分析,导致触发Region Server级别限制的因素主要有一个Region Server上运行的Region总数,
2、一个是Region上的Store数(即表的ColumnFamily数)。
3、对于前者,根据读写请求量一般建议线上一个Region Server上运行的Region保持在50~80个左右,太小的话会浪费资源,太大的话有可能触发其他异常;
4、对于后者,建议ColumnFamily越少越好,如果从逻辑上确实需要多个ColumnFamily,最好控制在3个以内。

小伙伴的问题1:
一个查询需要查一个Store中的mem和file。
如果发现block在blockcache中会去blockcache中读取,就可以不需要去读取那个file。
mem是肯定要被读取(否则读取的数据有问题)。
cache和file两者不一定,但是新生成的file如果没有被读取过肯定不在blockcache中。
答:
基本正确

小伙伴的问题2:
在memstore flush 机制中 *****
4、当一个Region Server中HLog数量达到上限(可通过参数hbase.regionserver.maxlogs配置)时,系统会选取最早的一个 HLog对应的一个或多个Region进行flush。
“一个Region Server中HLog数量” 不就只有一个嘛,为什么一个region server 的hlog数量之说,而且博主在“HBase - 数据写入流程解析”里面也说了“每个Region Server拥有一个HLog日志”。这边描述是否有点问题。不是很明白,还是博主解答。

答:
《HBase - 数据写入流程解析》中说到“每个Region Server拥有一个HLog日志”是想强调所有Region共用HLog。一个Region Server中所有Region都会向同一个HLog写日志,当HLog大小超过阈值就会新生成一个HLog文件接收新的写入。所以HLog文件个数实际上有多个的。

小伙伴的问题3:
因此HBase在读取数据的时候首先检查请求的数据是否在Memstore,写缓存未命中的话再到读缓存中查找,读缓存还未命中才会到HFile文件中查找,
———————————————
你好!这里我有个疑问,假如我是scan查询,写缓存或者读缓存只有部分数据满足要求,这时服务端是直接返回这部分数据,还是会继续到HFile中查找
答:
全部查询得到所有结果之后统一返回

参考链接: http://hbasefly.com/2016/03/23/hbase-memstore-flush/

原文地址:https://blog.51cto.com/12445535/2370770

时间: 2024-10-04 17:10:03

HBase – Memstore Flush和flush shell操作 深度解析的相关文章

HBase的SHELL操作和API

1.表结构: 2.SHELL操作 命令:hbase shell 显示表:list 创建表:create 'tb_name','column_family_1','column_family_2',...; 或者 create 'user', {NAME => 'column_family_1', VERSIONS => '3'} 插入数据:put 'tb_name','rk_on','column_family : key','value' 获取数据: 获取所有数据:get 'tb_name'

Hbase快速开始——shell操作

一. 介绍 HBase是一个分布式的.面向列的开源数据库,源于google的一篇论文<bigtable:一个结构化数据的分布式存储系统>.HBase是Google Bigtable的开源实现,它利用Hadoop HDFS作为其文件存储系统,利用Hadoop MapReduce来处理HBase中的海量数据,利用Zookeeper作为协同服务.  HBase以表的形式存储数据.表有行和列组成.列划分为若干个列族/列簇(column family).       如上图所示,key1, key2,

hbase之python利用thrift操作hbase数据和shell操作

前沿: 以前都是用mongodb的,但是量大了,mongodb显得不那么靠谱,改成hbase撑起一个量级. HBase是Apache Hadoop的数据库,能够对大型数据提供随机.实时的读写访问.HBase的目标是存储并处理大型的数据.HBase是一个开源的,分布式的,多版本的,面向列的存储模型.它存储的是松散型数据. HBase提供了丰富的访问接口. HBase Shell Java clietn API Jython.Groovy DSL.Scala REST Thrift(Ruby.Pyt

HBASE之shell操作和Java访问

对数据库HBASE的操作有shell端和java API两种方式. 在此之前要先说一下HBASE的结构及其数据存储结构: HBASE是基于HDFS的,是一种NoSQL的数据库.它的数据模型如下所示: Row Key Timestamp Column Family URI Parser r1 t3 url=http://www.taobao.com title=天天特价 t2 host=taobao.com   t1     r2 t5 url=http://www.alibaba.com con

hbase shell操作语句

2019/2/19 星期二 hbase shell操作语句基本shell 命令 进入hbase 命令行./hbase shell显示hbase 中的表list创建user 表,包含info.data 两个列族create 'user', 'info1', 'data1'create 'user', {NAME => 'info', VERSIONS => '3'}向user 表中插入信息,row key 为rk0001,列族info 中添加name 列标示符,值为zhangsanput 'us

HBase ——Shell操作

HBase ——Shell操作 Q:你觉得HBase是什么? A:一种结构化的分布式数据存储系统,它基于列来存储数据. 基于HBase,可以实现以廉价PC机器集群存储海量数据的分布式数据库的解决方案. 一般用于数据量巨大但查询简单的场景,典型场景包括:账单记录,订单流水,交易记录,数据库的历史记录 建立表 HBase中没有数据库的概念,但是存在命名空间的概念,在使用上类似库名,但实际上只是一个目录名. 另外要记住,HBase中大部分数据都是以HashMap的形式组织的,因此很多时候都能看到类似

Hbase数据结构和shell操作

Hbase的数据结构 基本要素:命名空间.表.行.列.单元格,region,时间戳. 1.命名空间:NameSpaces的作用 Table:表,所有的表都是命名空间的成员,即表必属于某个命名空间,如果没有指定,则在default默认的命名空间中. RegionServer group:一个命名空间包含了默认的RegionServer Group. Permission:权限,命名空间能够定义访问控制列表ACL(Access Control List).例如,创建表,读取表,删除,更新等等操作.

HBase的工作原理和相关操作

学习一个开源软件的基本思路都是(1)安装和配置(2)理解工作原理(3)命令操作(4)代码操作(5)研究源码(6)根据论文或需求进行二次开发.同样,学习HBase也不例外,但我省去了HBase集群(4台)的安装和配置,主要总结HBase的工作原理,Shell命令操作,Java代码操作相关内容. 一. HBase存储结构 1. Client 解析: 对于管理类的操作,Client与HMaster进行RPC,对于数据读写类的操作,Client与HRegionServer进行RPC. 2. ZooKee

hbase数据写入流程深度解析

2019/3/28 星期四hbase数据写入流程深度解析在看此链接之前,可以写查看 hbase读写请求详细解释 中的写请求流程 https://blog.51cto.com/12445535/2356085 简介:hbase设置之初就是为了应对大量的写多读少的应用,他出色的写性能,在一个100台RS的集群可以轻松地支撑每天10T的写入量.hbase的写数据流程大体分为3部分1.客户端的写入流程2.服务端的写入流程3.wal的工作原理 我们先回顾一下hbase写数据流程写请求处理过程小结1 cli