Hbase 读数据流程
7. 如果 BlockCache 中也没有,再到 StoreFile 上进行读取。从 StoreFile 中读到数据后,不是直接把结果返回给客户端,而是先把数据写入 BlockCache,然后再返回给客户端。
HBase 写数据流程
Flush 机制
1.当 memstore 的大小超过这个值的时候,会 flush 到磁盘,默认为 128M
hbase.hregion.memstore.flush.size
134217728
2. 当 memstore 的数据超过 1 小时,会 flush 到磁盘
hbase.regionserver.optionalcacheflushinterval
3600000
3. HregionServer 的全局 memstore 的大小,超过该大小会触发 flush 到磁盘的操作,默认是堆大小的 40%
hbase.regionserver.global.memstore.size
0.4
4. 手动 flush
flush tableName
阻塞机制
以上介绍了数据刷写磁盘的标准,但是 HBase 是周期性的检查是否满足来进行刷写的,如果在下次检查到来之前,数据疯狂写入 Memstore,就会把内存撑爆。那怎么处理这种问题呢?
HBase 有阻塞机制,如果触发,就无法继续写入数据。
1.当 Memstore 数据达到 512MB
计算公式:hbase.hregion.memstore.flush.size*hbase.hregion.memstore.block.multiplier
2.RegionServer 全部 memstore 达到规定值
有时候集群的“写负载”非常高,写入量一直超过 flush 的量,这时,我们就希望 memstore 不要超过一定的安全设置。在这种情况下,写操作就要被阻塞一直到 memstore 恢复到一个“可管理”的大小, 这个大小就是默认值是堆大小 *0.4 *0.95。
Compact 合并机制
在 HBase 中主要存在两种类型的 compact 合并。
1.Minor compact 小合并
将 Store 中的多个 HFile(StoreFile)合并为一个 HFile
这个过程中,删除和更新的数据仅仅只是做了标记,并没有物理移除,这种合并的触发频率很高。
minor compact 文件选择标准由以下几个参数共同决定:
hbase.hstore.compaction.min
3
hbase.hstore.compaction.max
10
hbase.hstore.compaction.min.size
134217728
hbase.hstore.compaction.max.size
9223372036854775807
触发条件
在进行 memstore flush 前后会进行判断是否触发 compact
周期性检查是否需要进行 compaction 操作,周期性时间由参数:hbase.server.thread.wakefrequency 决定,默认值是 10000 millseconds。
2.major compact 大合并
合并 Store 中所有的 HFile 为一个 HFile。
这个过程中有删除标记的数据会真正被移除,同时超过单元格 maxVersion 的版本记录也会被删除。合并频率比较低,默认 7 天执行一次,并且性能消耗非常大。建议生产关闭。在应用空闲时间手动触发。这样可以防止出现在业务高峰期进行 compact
触发条件
hbase.hregion.majorcompaction
604800000
手动触发
major_compact tableName
当 Region 中存储的是大量的 rowkey 数据,当 Region 中的数据条数过多的时候,直接影响查询效率。当 Region 过大的时候,HBase 就会拆分 Region。
拆分策略
HBase 的 Region Split 策略一共有以下几种:
1.ConstantSizeRegionSplitPolicy
但是在生产线上这种切分策略却有相当大的弊端:切分策略对于大表和小表没有明显的区分。阈值(hbase.hregion.max.filesize)设置较大对大表比较友好,但是小表就有可能不会触
发分裂,极端情况下可能就 1 个,这对业务来说并不是什么好事。如果设置较小则对小表友好,但一个大表就会在整个集群产生大量的 region,这对于集群的管理、资源使用、failover 来
说都不是一件好事
2.IncreasingToUpperBoundRegionSplitPolicy
切分策略稍微有点复杂,总体看和 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 了
3.SteppingSplitPolicy
这种切分策略的切分阈值又发生了变化,相比 IncreasingToUpperBoundRegionSplitPolicy 简单了一些,依然和待分裂 region 所属表在当前 regionserver 上的 region 个数有关系,如果 region 个数等于 1,切分阈值为 flushsize*2,否则为 MaxRegionFileSize。
这种切分策略对于大集群中的大表、小表会比 IncreasingToUpperBoundRegionSplitPolicy 更加友好,小表不会再产生大量的小 region,而是适可而止。
4.KeyPrefixRegionSplitPolicy
根据 rowKey 的前缀对数据进行分组,这里是指定 rowKey 的前多少位作为前缀,比如 rowKey 都是 16 位的,指定前 5 位是前缀,那么前 5 位相同的 rowKey 在进行 regionsplit 的时候会分到相同的 region 中。
5.DelimitedKeyPrefixRegionSplitPolicy
保证相同前缀的数据在同一个 region 中,例如 rowKey 的格式为:userideventtype_eventid,指定的 delimiter 为,则 split 的的时候会确保 userid 相同的数据在同一个 region 中
6.DisabledRegionSplitPolicy
不启用自动拆分, 需要指定手动拆分
拆分策略的应用
Region 拆分策略可以全局统一配置,也可以为单独的表指定拆分策略
1.通过 hbase-site.xml 全局统一配置,也可以为单独的表指定拆分策略
hbase.regionserver.region.split.policy
org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy
2.通过 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);
3.通过 HBase Shell 为单个表指定 Region 拆分策略
> create 'test2', {METADATA => {'SPLIT_POLICY' =>
'org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy'}},{NAME => 'cf1'}
1.为什么要预分区?
当一个 table 刚被创建的时候,HBase 默认分配一个 region 给 table。也就是说这个时候,所有的读写请求都会访问同一个 regionServer 的同一个 region 中,这个时候就达不到负载均衡的效果了,集群中其他的 regionServer 就可能会处于比较空闲的状态。解决这个问题可以用 pre-splitting。在创建 table 的时候就配置好,生成多个 region。
好处就是:
每个 region 维护着 startRow 与 endRowyKey,如果加入的数据符合某个 region 维护的 rowkey 范围,则该数据交给这个 region 来维护。
2.手动指定预分区
create ‘person’,‘info1’,‘info2’,SPLITS => [‘1000’,‘2000’,‘3000’]
也可以把分区规则创建于文件中。
create ‘student’,‘info’,SPLITS_FILE => ‘/root/hbase/split.txt’
Region 的合并不是为了性能,而是出于维护的目的。
Region 合并的方式:
1.通过 Merge 类冷合并
需要先关闭 HBase 集群。
不需要进入 hbase shell,直接执行:
合并的信息可以从页面上获取
hbase org.apache.hadoop.hbase.util.Merge user user,,1662823434957.f971c62e76cdff90ea957c0709099bb5. user,1000,1662823434957.366fc3c5e6237a8993cc0e143109c229.
2.通过 online_merge 热合并 Region
不需要关闭 HBase 集群,在线进行合并
与冷合并不同的是,online_merge 的传参是 Region 的 hash 值,Region 的 hash 值就是 Region 名称的最后那段在两个“.”之间的字符串部分。
示例:
merge_region 'c8d1a1b7f709dfcd8b0c574b4121fdca','1d7e67e13a48b67d2d7867ca9717183c'
留言与评论(共有 0 条评论) “” |