HBase数据读写分析详解

HBase数据的写入和读取流程

1、写数据流程

在这里插入图片描述

1)Client先访问Zookeeper,获取hbase:meta表位于哪个RegionServer。(元数据meta保存在zookeeper)

2)访问对应的RegionServer,获取hbase:meta表,根据读请求的namespace:table/rowkey,查询出目标数据位于哪个RegionServer中的哪个Region中。并将该table的region信息以及meta表的位置信息缓存在客户端的meta cache,方便下次访问。

3)与目标RegionServer进行通讯;

4)将数据顺序写入(追加)到WAL;(因为是顺序写,所以速度很快)

5)将数据写入对应的MemStore,数据会在MemStore进行排序;

6)向客户端发送ack;

7)等达到MemStore的刷写时机后,将数据以HFile格式刷写到storefile(就是存储到hdfs的过程)。

(等memstore中的数据刷写到hdfs中之后,hlog会将相应已经刷写的数据删除掉)

那么问题来了,memstore中的数据是何时刷写到hdfs的呢?

2、MemStore Flush

在这里插入图片描述

触发条件

1)MemStore级别
当某个MemStore的大小达到了hbase.hregion.memstore.flush.size(默认值128M),会触发MemStore的刷写。

(刷写到磁盘是以region为单位而不是以memstore为单位,一个region可能有多个store即有多个memstore,当一个region中的某个memstore达到128m时就会刷写整个region到hdfs,假如此时该region中其他的memstore才1kb,等于生成了很多小文件,所以实际应用中一个region通常只有一个store,一个store表示一个列簇的数据)。

2)HRegion级别
当Region中的MemStore的大小达到了
hbase.hregion.memstore.flush.size(默认值128M)X hbase.hregion.memstore.block.multiplier(默认值4),即总的memstore达到了512M时,会阻止继续往该MemStore写数据。

(当处于写数据高峰时,即使memstore达到了128M时也不会刷写,而是继续缓存,当达到512M (默认值时4倍)时,此时阻塞写入数据到memstore,将memstore缓存的数据刷写到hdfs之后才允许继续写入数据到memstore)。

3)HRegionServer级别
当RegionServer中MemStore的总大小达到
java_heapsize*hbase.regionserver.global.memstore.size.upper.limit(默认值0.95),
Server会按照其所有region中MemStore占有内存和的大小顺序(由大到小)依次以region为单位进行刷写。
当RegionServer中MemStore的总大小达到  java_heapsize*hbase.regionserver.global.memstore.size.lower.limit(默认值0.4)
时,会阻止继续往所有的MemStore写数据

java_heapsize:指的是服务器分配给hbase的总内存大小。

例如服务器总内存64G,分配给hbase的内存为10G,那么当regionserver中的memstore占用内存之和达到0.95*10G时开始依次刷写到hdfs,直到占用内存之和低于0.4*10G停止刷写,继续写数据到memstore。
4)HLog级别
当WAL文件的数量超过hbase.regionserver.maxlogs,region会按照时间顺序依次进行刷写,直到WAL文件数量减小到hbase.regionserver.maxlogs以下(该属性名已经废弃,现无需手动设置,最大值为32)。(wal文件按时间滚动当达到32个wal文件时刷写数据)
5)定期刷写
到达自动刷写的时间,也会触发MemStore flush。自动刷新的时间间隔由该属性进行配置hbase.regionserver.optionalcacheflushinterval(默认1小时),指的是当前MemStore最后一次编辑时间。
6)手动刷写
用户通过shell命令“flush ‘table’”或者“flush ‘regionname’”分别对一个Region或者多个Region进行flush

3、读数据流程

在这里插入图片描述

1)Client先访问Zookeeper,获取hbase:meta表位于哪个RegionServer。

(元数据只有一个region,保存在一个regionserver上)

2)访问对应的RegionServer,获取hbase:meta表,根据读请求的namespace:table/rowkey,查询出目标数据位于哪个RegionServer中的哪个Region中。并将该table的region信息以及meta表的位置信息缓存在客户端的meta cache,方便下次访问。

3)与目标RegionServer进行通讯;

4)分别在BlockCache(内存),MemStore中查询目标数据,如果BlockCache和MemStore中未查到相应数据,则扫描对应的HFile文件,HFile中扫描到的数据块(默认64K)写入BlockCache,并将查到的所有数据进行合并。

此处所有数据是指同一条数据的不同版本(timestamp)或者不同的类型(Put/Delete)。

(在扫面storeFile中的Hfile文件时会先经过Bloom Filter即布隆过滤器,速度非常快。)

5)将合并后的最终结果返回给客户端。

4、StoreFile Compaction(文件合并)

在这里插入图片描述

为什么要进行文件合并呢?

(1)原因:

由于memstore每次刷写都会生成一个新的HFile,且同一个字段的不同版本(timestamp)和不同类(Put/Delete)有可能会分布在不同的HFile中,因此查询时需要遍历所有的HFile,影响查询性能。为了减少HFile的个数,以及清理掉过期和删除的数据,会进行StoreFile Compaction。

Compaction分为两种,分别是Minor CompactionMajor Compaction

(2)Minor Compaction

会将临近的若干个较小的HFile合并成一个较大的HFile,但【不会】清理过期和删除的数据。(128M以下称为小文件,小文件达到3个时合并成一个大文件)

(3)Major Compaction

Major Compaction会将一个Store下的所有的HFile合并成一个大HFile,并且【会】清理掉过期和删除的数据。(每隔7天将所有的hfile合并成一个大文件,实际应用中一般关闭此项,自己手动Major Compaction,命令为major_compact ‘表名’,因为非常消耗性能)

5、Region Split(文件拆分)

(1)原因:

默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的Region Server,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的Region Server。

那么问题来了,何时对文件进行拆分呢?

(2)拆分时机

0.94版本之前:

使用的是ConstantSizeRegionSplitPolicy策略

当1个region中的某个Store下所有StoreFile的总大小超过hbase.hregion.max.filesize(10G),该Region就会进行拆分。
0.94版本-2.0版本:

使用的是IncreasingToUpperBoundRegionSplitPolicy策略

当1个Region中的某个Store下所有StoreFile的总大小超过Min(R^3 * "hbase.hregion.memstore.flush.size",hbase.hregion.max.filesize"),该Region就会进行拆分。
其中R为当前Region Server中该Region所属Table的Region个数(一个表可能分成多个Region)。
2.0版本:

使用的是SteppingSplitPolicy策略

当前RegionServer中属于该Table的Region个数为1,分裂阈值等于flushSize*2,也就是(128*2)M,否则为hbase.hregion.max.filesize(10G)。Region中文件总大小达到该阈值进行拆分。
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值