HBase原理深入
HBase 读写数据流程
Hbase 读数据流程
首先从 zk 找到 meta 表的 region 位置,然后读取 meta 表中的数据,meta 表中存储了用户表的 region 信息
根据要查询的 namespace、表名和 rowkey 信息,找到写入数据对应的 region 信息
找到这个 region 对应的 regionServer,然后发送请求
查找对应的 region
先从 Memstore 查找数据,如果没有,再从 BlockCache 上读取。
Hbase 上 RegionServer 的内存分为两部分:
- 一部分作为 Memstore,主要用来写
- 另一部分作为 BlockCache,主要用来读数据
如果 BlockCache 中也没有,再到 StoreFile 上进行读取。从 StoreFile 中读到数据后,不是直接把结果返回给客户端,而是先把数据写入 BlockCache,然后再返回给客户端。
HBase 写数据流程
- 首先从 zk 找到 meta 表的 region 位置,然后读取 meta 表中的数据,meta 表中存储了用户表的 region 信息。
- 根据 namespace、表名和 rowkey 等信息,找到写入数据对应的 region
- 找到这个 region 对应的 regionServer,然后发送写入请求
- 把数据分别写入 HLog(Write ahead log)和 memStore
- memStore 达到阈值后把数据刷到磁盘,生成 storeFile
- 删除 HLog 中的历史数据
HBase 的 flush(刷写)和 compact(合并)机制
Flush 机制
- 当 memstore 的大小超过这个值的时候,会 flush 到磁盘,默认为 128M
<property>
<name>hbase.hregion.memstore.flush.size</name>
<value>134217728</value>
</property>
- 当 memstore 的数据超过 1 小时,会 flush 到磁盘
<property>
<name>hbase.regionserver.optionalcacheflushinterval</name>
<value>3600000</value>
</property
- HregionServer 的全局 memstore 的大小,超过该大小会触发 flush 到磁盘的操作,默认是堆大小的 40%
<property>
<name>hbase.regionserver.global.memstore.size</name>
<value>0.4</value>
</property>
- 手动 flush
flush tableName
阻塞机制
以上介绍了数据刷写磁盘的标准,但是 HBase 是周期性的检查是否满足来进行刷写的,如果在下次检查到来之前,数据疯狂写入 Memstore,就会把内存撑爆。那怎么处理这种问题呢?
HBase 有阻塞机制,如果触发,就无法继续写入数据。
- 当 Memstore 数据达到 512MB
计算公式:hbase.hregion.memstore.flush.size*hbase.hregion.memstore..block.multiplier
- hbase.hregion.memstore.flush.size 刷写的阀值,默认是 134217728,即 128MB。
- hbase.hregion.memstore.block.multiplier 是一个倍数,默认是 4。
- RegionServer 全部 memstore 达到规定值
有时候集群的“写负载”非常高,写入量一直超过 flush 的量,这时,我们就希望 memstore 不要超过一定的安全设置。在这种情况下,写操作就要被阻塞一直到 memstore 恢复到一个“可管理”的大小, 这个大小就是默认值是堆大小 _ 0.4 _ 0.95。
- hbase.regionserver.global.memstore.size.lower.limit 是 0.95
- hbase.regionserver.global.memstore.size 是 0.4
Compact 合并机制
在 HBase 中主要存在两种类型的 compact 合并。
- Minor compact 小合并
将 Store 中的多个 HFile(StoreFile)合并为一个 HFile
这个过程中,删除和更新的数据仅仅只是做了标记,并没有物理移除,这种合并的触发频率很高。
minor compact 文件选择标准由以下几个参数共同决定:
<!--待合并文件数据必须大于等于下面这个值-->
<property>
<name>hbase.hstore.compaction.min</name>
<value>3</value>
</property>
<!--待合并文件数据必须小于等于下面这个值-->
<property>
<name>hbase.hstore.compaction.max</name>
<value>10</value>
</property>
<!--默认值为128m,
表示文件大小小于该值的store file 一定会加入到minor compaction的store file中
-->
<property>
<name>hbase.hstore.compaction.min.size</name>
<value>134217728</value>
</property>
<!--默认值为LONG.MAX_VALUE,
表示文件大小大于该值的store file 一定会被minor compaction排除-->
<property>
<name>hbase.hstore.compaction.max.size</name>
<value>9223372036854775807</value>
</property>
触发条件
- memstore flush
在进行 memstore flush 前后会进行判断是否触发 compact
- 定期检查线程
周期性检查是否需要进行 compaction 操作,周期性时间由参数:hbase.server.thread.wakefrequency 决定,默认值是 10000 millseconds。
- major compact 大合并
合并 Store 中所有的 HFile 为一个 HFile。
这个过程中有删除标记的数据会真正被移除,同时超过单元格 maxVersion 的版本记录也会被删除。合并频率比较低,默认 7 天执行一次,并且性能消耗非常大。建议生产关闭。在应用空闲时间手动触发。这样可以防止出现在业务高峰期进行 compact
触发条件
<!--默认值为7天进行一次大合并,-->
<property>
<name>hbase.hregion.majorcompaction</name>
<value>604800000</value>
</property>
手动触发
major_compact tableName
Region 拆分机制
当 Region 中存储的是大量的 rowkey 数据,当 Region 中的数据条数过多的时候,直接影响查询效率。当 Region 过大的时候,HBase 就会拆分 Region。
拆分策略
HBase 的 Region Split 策略一共有以下几种:
- ConstantSizeRegionSplitPolicy
- 0.94 版本前默认切分策略
当 region 大小大于某个阈值(hbase.hregion.max.filesize=10G)之后就会触发切分,一个 region 等分为 2 个 region。
但是在生产线上这种切分策略却有相当大的弊端:切分策略对于大表和小表没有明显的区分。阈值(hbase.hregion.max.filesize)设置较大对大表比较友好,但是小表就有可能不会触
发分裂,极端情况下可能就 1 个,这对业务来说并不是什么好事。如果设置较小则对小表友好,但一个大表就会在整个集群产生大量的 region,这对于集群的管理、资源使用、failover 来
说都不是一件好事
- IncreasingToUpperBoundRegionSplitPolicy
- 0.94 版本~2.0 版本默认切分策略
切分策略稍微有点复杂,总体看和 ConstantSizeRegionSplitPolicy 思路相同,一个 region 大小大于设置阈值就会触发切分。但是这个阈值并不像 ConstantSizeRegionSplitPolicy 是一个固定的值,而是会在一定条件下不断调整,调整规则和 region 所属表在当前 regionserver 上的 region 个数有关系.
region split 的计算公式是:
regioncount^3 _ 128M _ 2,当 region 达到该 size 的时候进行 split:
例如::
第一次 split:1^3 _ 256 = 256MB:
第二次 split:2^3 _ 256 = 2048MB:
第三次 split:3^3 _ 256 = 6912MB:
第四次 split:4^3 _ 256 = 16384MB > 10GB,因此取较小的值 10GB:
后面每次 split 的 size 都是 10GB 了
- SteppingSplitPolicy
- 2.0 版本默认切分策略
这种切分策略的切分阈值又发生了变化,相比 IncreasingToUpperBoundRegionSplitPolicy 简单了一些,依然和待分裂 region 所属表在当前 regionserver 上的 region 个数有关系,如果 region 个数等于 1,切分阈值为 flushsize*2,否则为 MaxRegionFileSize。
这种切分策略对于大集群中的大表、小表会比 IncreasingToUpperBoundRegionSplitPolicy 更加友好,小表不会再产生大量的小 region,而是适可而止。
- KeyPrefixRegionSplitPolicy
根据 rowKey 的前缀对数据进行分组,这里是指定 rowKey 的前多少位作为前缀,比如 rowKey 都是 16 位的,指定前 5 位是前缀,那么前 5 位相同的 rowKey 在进行 regionsplit 的时候会分到相同的 region 中。
- DelimitedKeyPrefixRegionSplitPolicy
保证相同前缀的数据在同一个 region 中,例如 rowKey 的格式为:userideventtype_eventid,指定的 delimiter 为,则 split 的的时候会确保 userid 相同的数据在同一个 region 中
- DisabledRegionSplitPolicy
不启用自动拆分, 需要指定手动拆分
拆分策略的应用
Region 拆分策略可以全局统一配置,也可以为单独的表指定拆分策略
- 通过 hbase-site.xml 全局统一配置,也可以为单独的表指定拆分策略
<property>
<name>hbase.regionserver.region.split.policy</name>
<value>org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy</value>
</property>
- 通过 Java API 为单独的表指定 Region 拆分策略
HTableDescriptor tableDesc = new HTableDescriptor("test1");
tableDesc.setValue(HTableDescriptor.SPLIT_POLICY, IncreasingToUpperBoundRegionSplitPolicy.class.getName());
tableDesc.addFamily(new HColumnDescriptor(Bytes.toBytes("cf1")));
admin.createTable(tableDesc);
- 通过 HBase Shell 为单个表指定 Region 拆分策略
> create 'test2', {METADATA => {'SPLIT_POLICY' =>
'org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy'}},{NAME => 'cf1'}
HBase 表的预分区
- 为什么要预分区?
当一个 table 刚被创建的时候,HBase 默认分配一个 region 给 table。也就是说这个时候,所有的读写请求都会访问同一个 regionServer 的同一个 region 中,这个时候就达不到负载均衡的效果了,集群中其他的 regionServer 就可能会处于比较空闲的状态。解决这个问题可以用 pre-splitting。在创建 table 的时候就配置好,生成多个 region。
好处就是:
- 增加数据读写效率
- 负载均衡,防止数据倾斜
- 方便集群容灾调度 region
每个 region 维护着 startRow 与 endRowyKey,如果加入的数据符合某个 region 维护的 rowkey 范围,则该数据交给这个 region 来维护。
- 手动指定预分区
create 'person','info1','info2',SPLITS => ['1000','2000','3000']
也可以把分区规则创建于文件中。
create 'student','info',SPLITS_FILE => '/root/hbase/split.txt'
Region 合并
Region 的合并不是为了性能,而是出于维护的目的。
Region 合并的方式:
- 通过 Merge 类冷合并
需要先关闭 HBase 集群。
不需要进入 hbase shell,直接执行:
合并的信息可以从页面上获取
hbase org.apache.hadoop.hbase.util.Merge user user,,1662823434957.f971c62e76cdff90ea957c0709099bb5. user,1000,1662823434957.366fc3c5e6237a8993cc0e143109c229.
- 通过 online_merge 热合并 Region
不需要关闭 HBase 集群,在线进行合并
与冷合并不同的是,online_merge 的传参是 Region 的 hash 值,Region 的 hash 值就是 Region 名称的最后那段在两个“.”之间的字符串部分。
示例:
merge_region 'c8d1a1b7f709dfcd8b0c574b4121fdca','1d7e67e13a48b67d2d7867ca9717183c'
HBase原理深入的更多相关文章
- HBase笔记:对HBase原理的简单理解
早些时候学习hadoop的技术,我一直对里面两项技术倍感困惑,一个是zookeeper,一个就是Hbase了.现在有机会专职做大数据相关的项目,终于看到了HBase实战的项目,也因此有机会搞懂Hbas ...
- Hbase原理
Hbase原理 概述 HBase是一个构建在HDFS上的分布式列存储系统:HBase是基于Google BigTable模型开发的,典型的key/value系统:HBase是Apache Hadoop ...
- HBase原理、设计与优化实践
转自:http://www.open-open.com/lib/view/open1449891885004.html 1.HBase 简介 HBase —— Hadoop Database的简称,G ...
- 大数据技术之_11_HBase学习_01_HBase 简介+HBase 安装+HBase Shell 操作+HBase 数据结构+HBase 原理
第1章 HBase 简介1.1 什么是 HBase1.2 HBase 特点1.3 HBase 架构1.3 HBase 中的角色1.3.1 HMaster1.3.2 RegionServer1.3.3 ...
- 1、Hbase原理分析
一.Hbase介绍 1.1.对Hbase的认识 HBase作为面向列的数据库运行在HDFS之上,HDFS缺乏随机读写操作,HBase正是为此而出现. HBase参考 Google 的 Bigtable ...
- HBase原理 – 分布式系统中snapshot是怎么玩的?(转载)
snapshot(快照)基础原理 snapshot是很多存储系统和数据库系统都支持的功能.一个snapshot是一个全部文件系统.或者某个目录在某一时刻的镜像.实现数据文件镜像最简单粗暴的方式是加锁拷 ...
- 【转】HBase原理和设计
简介 HBase —— Hadoop Database的简称,Google BigTable的另一种开源实现方式,从问世之初,就为了解决用大量廉价的机器高速存取海量数据.实现数据分布式存储提供可靠的方 ...
- HBase原理和设计
转载 2016年1月10日:http://www.sysdb.cn/index.php/2016/01/10/hbase_principle/ 简介 架构 数据组织 原理 RS定位 region写入 ...
- HBase原理解析(转)
本文属于转载,原文链接:http://www.aboutyun.com/thread-7199-1-1.html 前提是大家至少了解HBase的基本需求和组件. 从大家最熟悉的客户端发起请求开始讲 ...
- HBase之一:HBase原理和设计
一.简介 HBase —— Hadoop Database的简称,Google BigTable的另一种开源实现方式,从问世之初,就为了解决用大量廉价的机器高速存取海量数据.实现数据分布式存储提供可靠 ...
随机推荐
- 解决github.com 的响应时间过长以及hosts配置不能保存的问题
github.com 的响应时间过长 1 获取github可以使用的DNS域名 DNS查询 选择TTL值最小的 2 修改hosts配置 打开之后在最后加上如下内容,保存即可 3 出现hosts不能保存 ...
- 基于.NetCore开发博客项目 StarBlog - (14) 实现主题切换功能
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- JavaWeb连接MySQL数据库
JavaWeb连接MySQL数据库 JavaWeb连接MySQL数据库的方式有很多,首先我们讲解JDBC的配置方法 一.JDBC的配置方法 1.什么是JDBC 什么是JDBC嘞?JDBC代表Java数 ...
- Graphics2D类
Graphics2D类 Java语言在Graphics类提供绘制各种基本的几何图形的基础上,扩展Graphics类提供一个Graphics2D类,它拥用更强大的二维图形处理能力,提供.坐标转换.颜色管 ...
- vlan配置
VLAN(Virtual Local Area Network)即虚拟局域网,是将一个物理的局域网在逻辑上划分成多个广播域的技术. 通过在交换机上配置VLAN,可以实现在同一个VLAN内的用户可以进行 ...
- NOI / 1.1编程基础之输入输出全题详解(8515字)
目录 01:Hello, World! 02:输出第二个整数 03:对齐输出 04:输出保留3位小数的浮点数
- VirtualBox 相关命令行
简介 由于之前项目有一个需求,则是自动化创建虚拟机并加载相关配置,创建虚拟机无法避免对于虚拟机系统的设置,因此采用导入虚拟机的方式,并通过查阅virtualbox相关手册,知晓virtualbox可以 ...
- 膜 社论(egg drop)
题面 \(n\) 楼 \(m\) 个鸡蛋,从 \(k\) 楼及以上扔下去会碎,不能再测试 . 问至少需要扔几次确定 \(k\) . \(n\le 10^{18}\),\(m\le 64\) . 题解 ...
- 学习nginx的一点记录
一.nginx定义 Nginx是一款轻量级的.高性能的,具备HTTP.反向代理.负载均衡的web服务器,同时还提供IMAP/POP3/SMTP服务,其特点是占用内存少,并发能力强. 二.nginx基本 ...
- DP 优化方法合集
0. 前言 写完这篇文章后发现自己对于 DP 的优化一窍不通,所以补了补 DP 的一些优化,写篇 blog 总结一下. 1. 单调队列/单调栈优化 1.2 算法介绍 这应该算是最基础的 DP 优化方法 ...