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的另一种开源实现方式,从问世之初,就为了解决用大量廉价的机器高速存取海量数据.实现数据分布式存储提供可靠 ...
随机推荐
- UiPath循环活动Do While的介绍和使用
一.Do While的介绍 先执行循环体, 再判断条件是否满足, 如果满足, 则再次执行循环体, 直到判断条件不满足, 则跳出循环 二.Do While在UiPath中的使用 1. 打开设计器,在设计 ...
- Python制作手游《和平精英》游戏资料查询助手
写在前面的一些P话: <和平精英>这个游戏想必大家都玩过了,今天来教大家制作一个<和平精英>游戏的资料查询助手 受害者地址: https://gp.qq.com/main.sh ...
- 给妹子讲python-S01E01好用的列表
1.python中的容器数据类型概述2.列表类型的异构性.有序性和本地可变性三大优势2.列表的基本操作(增.删.改.分片索引)3.列表的分片赋值与本地排序 [妹子说]今天开始学python啦,不过我们 ...
- python——进行年龄和性别检测
年龄和性别检测 使用Python编程语言带你完成使用机器学习进行年龄和性别检测的任务. 首先需要编写用于检测人脸的代码,因为如果没有人脸检测,我们将无法进一步完成年龄和性别预测的任务. 下一步是预测图 ...
- 微服务追踪SQL(支持Isto管控下的gorm查询追踪)
效果图 SQL的追踪正确插入到微服务的调用链之间 详细记录了SQL的执行内容和消耗时间 搜索SQL的类型 多线程(goroutine)下的追踪效果 在 Kubernetes 中部署微服务后,通过 Is ...
- 8.4 苹果macOS电脑如何安装Java开发环境(JDK)
和Windows电脑安装差不多. 下载 来到JDK官方下载界面,点击Java SE 8(简称JDK 8)后面的JDK下载,来到该界面,先同意协议,然后下载对应平台的JDK,我们这里下载Mac OS X ...
- 【RocketMQ】消息的拉取
RocketMQ消息的消费以组为单位,有两种消费模式: 广播模式:同一个消息队列可以分配给组内的每个消费者,每条消息可以被组内的消费者进行消费. 集群模式:同一个消费组下,一个消息队列同一时间只能分配 ...
- SpringMVC-01
1. 概述 1.1 概念 SpringMVC是一种基于Java实现MVC模型的轻量级Web框架 优点 使用简单,开发便捷(相比于Servlet) 灵活性强 项目请求响应架构演进: 软件三层 软件三层 ...
- Java编程作业
1.编程题 设计一个用户类User,类中的变量有用户名.密码和记录用户数量的变量,定义3个构造方法:无参的.为用户名赋值的.为用户名和密码赋值的,还有获取和设置密码的方法和返回类信息的方法. pack ...
- NFS介绍与搭建
一.NFS的介绍 1.1.什么是NFS NFS 是Network File System的缩写,即网络文件系统.一种使用于分散式文件系统的协定,由Sun公司开发,于1984年向外公布. NFS在文件传 ...