首页 > 其他分享 >三大操作之--split操作

三大操作之--split操作

时间:2023-12-11 22:33:21浏览次数:27  
标签:文件 RegionServer -- Region 切分 split 三大 Split

  Hbase Split 是一个很重要的功能,HBase 通过把数据分配到一定数量的 Region 来达到负载均衡的。当 Region 管理的数据过多时,可以通过手动或自动的方式触发 HBase Split 将一个 Region 分裂成两个新的子 Region,并对父 Region 进行清除处理(不会立即清除)。

HBase 为什么需要 Split?
相比于传统 RDBMS 对大数据表的扩展方式,HBase 天然支持自动分库分表,实现的基础就是 Split 和 Rebalance。
Region 是管理一段连续的 Rowkey 的核心单元,当 Region 管理的 Rowkey 数量多时,或 HFile 文件较大时,都会影响到性能。

Pre-splitting

一个表刚被创建的时候,Hbase 默认分配一个 Region 给表,所有的读写请求都会访问到一个 RegionServer 上的唯一一个 Region。这样就达不到负载均衡的效果了,集群中的其他 RegionServer 就会处于空闲的状态(考虑只有一个表的情况)。解决这个问题可以有两种方法:

  • 如果能很好的预计业务的 Rowkey 分布和数据增长情况,可以在建表时分配好 Region 的数量和每个 Region Rowkey 范围,同时禁用表的自动分区,因为 Split 操作会有额外的开销和维护成本。

  • 另一种方法只需要指定分配的 Region 数量,利用 pre-splitting,生成每个 Region 的 Rowkey 范围

Hbase 自带了两种 pre-split 的算法,分别是 HexStringSplit 和 UniformSplit 。HexStringSplit 适用于十六进制字符的 Rowkey(MD5)。UniformSplit 适用于随机字节组成的 Rowkey(Hash)。

Split 触发时机

HBase 中共有3种情况会触发 HBase Split:

  1. 当 Memstore flush 操作后,HRegion 写入新的 HFile,有可能产生较大的 HFile,会判断是否需要执行 Split。
  2. HStore 执行完成 Compact 操作后可能产生较大的 HFile,会判断是否需要执行 Split。
  3. HBaseAdmin 手动执行 split 命令时,会触发 Split。

Split 触发策略

目前已经的支持触发策略多达6种,每种触发策略都有各自的适用场景,可以根据业务在表级别(Column family 级别)选择不同的切分触发策略。一般情况下使用默认切分策略即可。

  • ConstantSizeRegionSplitPolicy:0.94版本前默认切分策略。
    一个 Region 中最大 Store 的大小大于设置阈值之后才会触发切分,Store 大小为压缩后的文件大小(启用压缩的场景)
    切分策略对于大表和小表没有明显的区分

  • IncreasingToUpperBoundRegionSplitPolicy:0.94版本~2.0版本默认切分策略。
    和 ConstantSizeRegionSplitPolicy 思路相同,一个 Region 中最大 Store 大小大于设置阈值就会触发切分,区别是这个阈值并不像 ConstantSizeRegionSplitPolicy 是一个固定的值,而是会在不断调整。
    调整规则和 Region 所属表在当前 RegionServer 上的 Region 个数有关系 :(#regions) * (#regions) * (#regions) * flush_size * 2,最大值为用户设置的 MaxRegionFileSize
    能够自适应大表和小表,这种策略下很多小表会在大集群中产生大量小 Region,分散在整个集群中

  • SteppingSplitPolicy:2.0版本默认切分策略。
    相比 IncreasingToUpperBoundRegionSplitPolicy 简单了一些,依然和待分裂 Region 所属表在当前 RegionServer 上的 Region 个数有关系:如果 Region 个数等于1,切分阈值为 flush_size * 2,否则为 MaxRegionFileSize

  • DisableSplitPolicy:禁止 Region split

  • KeyPrefixRegionSplitPolicy:切分策略依然依据默认切分策略,根据 Rowkey 指定长度的前缀来切分 Region,保证相同的前缀的行保存在同一个 Region 中。由 KeyPrefixRegionSplitPolicy.prefix_length 属性指定 Rowkey 前缀长度。按此长度对splitPoint进行截取。
    此种策略比较适合有固定前缀的 Rowkey。当没有设置前缀长度,切分效果等同与 IncreasingToUpperBoundRegionSplitPolicy。

  • DelimitedKeyPrefixRegionSplitPolicy:切分策略依然依据默认切分策略,同样是保证相同 RowKey 前缀的数据在一个Region中,但是是以指定分隔符前面的前缀为来切分 Region。

Split 流程

Region split 的过程可以简单的理解为:在 Region 中找到一个合适的 split point,在这个 split point 上将该 Region 的数据划分为两个新的 Region。当然这个过程的实现起来很复杂,Split 发生时,新创建的子 Region 不会立即将所有数据重新写入新文件,而是会创建类似于符号链接文件的小文件,称为引用文件(reference files),根据 split point,指向父存储文件的顶部或底部(父 Region 的一半数据)。

下文引用官方博客对 HBase split 流程的解释:


HBase Split HBase Split

HBase 将整个切分过程包装成了一个事务,为了保证切分事务的原子性。整个分裂事务过程分为三个阶段:prepare – execute – (rollback)

  • prepare阶段:在内存中初始化两个子 Region,具体是生成两个 HRegionInfo 对象,包含 TableName、RegionName、Startkey、Endkey等。同时会生成一个 transaction journal,这个对象用来记录切分的进展

  • execute阶段:切分的核心操作
    (1)在ZK节点 /hbase/region-in-transition/region-name 下创建一个 znode,并设置状态为SPLITTING
    (2)Master 通过监听ZK节点,检测到 Region 状态的变化
    (3)RegionServer 在父 Region 的数据目录(HDFS)下创建一个名称为 .splits 的子目录
    (4)RegionServer 关闭父 Region,强制将数据 flush 到磁盘,并这个 Region 标记为 offline 的状态。此时,落到这个 Region 的请求都会返回 NotServingRegionException 这个错误,客户端需要进行一些重试,直到新的 Region 上线。
    (5)RegionServer 在 .splits 目录(HDFS)下创建 daughterA 和 daughterB 子目录,并在文件夹中创建对应的 reference 文件,分别指向父 Region 的数据文件中的一部分。
    (6)RegionServer 创建子 Region 的目录(HDFS),并将 daughterA 和 daughterB 目录下的文件拷贝到 Region 目录。
    (7)在 .META. 表中设置父 Region 为 offline 状态,不再提供服务。并将子 Region 的信息添加到 .META. 表中父 Region 的信息中(splitA 和 splitB 两列)。这个时候如果扫描 hbase:meta 表,会发现父 Region 正在执行 split,并不能看到子 Region 的信息。如果 RegionServer 执行这个过程失败,Master 和下一个分配了这个 Region 的 Regionserver 会清除 split 相关的状态数据。
    (8)RegionServer 并行启用两个子 Region,并正式提供对外服务
    (9)RegionSever 将 daughterA 和 daughterB 添加到 .META. 表中,并设置为 online 状态,这样就可以从 .META. 找到子 Region,并可以对子 Region 进行访问了。
    (10)RegionServr 修改ZK节点 /hbase/region-in-transition/region-name 的状态为SPLIT,Master 就可以监听到 Region 状态的更新。Split 事务就此结束。

再次强调,为了减少对业务的影响,Region 的 Split 并不涉及到数据迁移的操作,而只是创建了对父Region的指向。只有在做大合并的时候,才会将数据进行迁移。

  • rollback阶段:如果 execute 阶段出现异常,则执行 rollback 操作。为了实现回滚,整个切分过程被分为很多子阶段,回滚程序会根据当前进展到哪个子阶段清理对应的垃圾数据。JournalEntryType 类定义了各个子阶段。

Region 事务性保证

整个region切分是一个比较复杂的过程,涉及子步骤,因此必须保证整个 Split 过程的事务性,即要么完全成功,要么完全未开始,在任何情况下也不能出现 Split 只完成一半的情况。为了实现事务性,Hbase 设计了使用状态机(见 SplitTransaction 类)的方式保存切分过程中的每个子步骤状态,这样一旦出现异常,系统可以根据当前所处的状态决定是否回滚,以及如何回滚。

目前实现中这些中间状态都只存储在内存中,因此一旦在切分过程中出现 RegionServer 宕机的情况,有可能会出现切分处于中间状态的情况,也就是RIT状态。这种情况下可使用 hbck 工具,根据实际情况查看并分析解决方案。

在2.0版本 HBase 实现了新的分布式事务框架 Procedure V2(HBASE-12439),使用 HLog 存储这种单机事务(DDL、Split、Move 等操作)的中间状态。保证即使在事务执行过程中参与者发生了宕机,依然可以使用 HLog 作为协调者对事务进行回滚操作或重新提交。

通过 reference 文件如何查找到对应的数据

根据文件名来判断是否是 reference 文件:

  1. reference 文件的命名规则为前半部分为父 Region 对应的 HFile 的文件名,后半部分是父 Region 的名称,因此读取的时候也根据前半部分和后半部分来定位文件。
  2. 根据 reference 文件的内容来确定扫描的范围,reference 的内容包含两部分:一部分是切分点 splitkey,另一部分是 boolean 类型的变量,如果为 true 则扫描文件的上半部分,反之则扫描文件的下半部分
  3. 接下来确定了扫描的文件,以及文件的扫描范围,那就按照正常的文件检索了

Split 对其他模块的影响

执行 Region Split 过程不涉及数据的移动,所以可以很快完成。新生成的子 Region 文件中没有任何用户数据,而是一个 reference 文件,文件中存储的是一些元数据信息,包括切分点的 Rowkey 等。引入了以下问题:

  1. 父 Region 的数据什么时候会迁移到子 Region 目录
    子 Region 发生 major_compaction 时。将父 Region 目录中属于该子 Region 的所有数据读出来并写入子 Region 数据文件目录中,这一操作符合 compaction 本身的处理逻辑,因此在 compaction 中操作。

  2. 父 Region 什么时候会被删除
    HMaster 会启动一个线程定期检查所有处于 splitting 状态的父 Region,确定其是否可以被清理。检测线程首先会在 .META. 表中找到 splitting region,并找出其生成的两个子 Region(.META. 表中 splitA 和 splitB 列)。然后检查两个子 Region 是否保留引用文件,如果都不存在就认为该 splitting region 可以被删除和下线。.META. 表中的信息参考下图:

注意事项

使用 Split 时有以下需要注意的:

  1. 不能对元数据表进行 Split
  2. 不能对正在恢复的 Region 进行 Split
  3. 如果某个 Region 存在引用文件的不能 Split
  4. 当 Split 执行到将父 Region 下线之后,子 Region还未创建之前,如果此刻正访问的是父 Region,在客户端没有更新 Region 地址缓存的情况下,会报 NotServingRegionException 异常,因此客户端需要做好重试机制。
  5. Split 的完整过程中有个关键的时间点是无法回退的点(PONR: point of no return),发生在将 .META. 表中的父 Region 下线之前,如果进入 PONR 之后,由于种种原因更新 .META. 失败,需要重启所在的 RegionServer。


作者:Alex90
链接:https://www.jianshu.com/p/53459997c814
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

标签:文件,RegionServer,--,Region,切分,split,三大,Split
From: https://www.cnblogs.com/guoyu1/p/17895752.html

相关文章

  • js 传参到 vue + 计算属性使用
    场景js中存储xAxisData=[......]、yAxisData=[......],想在vue中使用,但要求使用前转化成data存有若干个(x,y)的形式在改变xAxisData或yAxisData的任意一值时,都会反馈更新到vue的每一个调用了data的地方方法一:js中Cannotreadpropertiesofundefine......
  • echarts 图
    ECHARTS官网:Examples-ApacheECharts各图图标可以参考:iconfont-阿里巴巴矢量图标库ECHARTS官网找想要的图,然后打开:右边是可视化的图形显示,左边是:代码编辑:只有内含的属性配置,可以在里面编写属性,然后即刻运行在右侧显示完整代码:显示右侧图形的整个vue代码,拿来......
  • 树莓派设置开启启动程序
    通过修改/etc/rc.local文件设置开机启动程序打开/etc/rc.local文件:sudonano/etc/rc.local在文件的exit0之前,添加你的启动程序命令。确保在命令末尾加上&,使其在后台运行。例如:/path/to/your/startup_script.sh&替换/path/to/your/startup_script.sh为实际......
  • CPU空闲时间管理 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/driver-api/pm/cpuidle.htmlCPU空闲时间管理版权©2019IntelCorporation作者[email protected]空闲时间管理子系统系统中的每个逻辑CPU(看起来获取和执行指令的实体:如果存在的话,硬件线程或处理器......
  • Redis内存淘汰策略
    Redis内存过期策略定时过期设置有效时间的key一旦过期,立马从内存中删除。好处就是内存及时释放,坏处就是不停扫描key,cpu消耗严重惰性过期设置有效时间的key过期,不立马删除key,而是等下一次查询到该key时执行删除动作。好处就是cpu消耗降低,坏处就是消耗内存定期过期每过一段时......
  • 浮点数与定点数相互转换(仅考虑正数情况)
    1.浮点数转换为定点数定点数总位宽设为\(W\),小数部分字长设为\(F\)那么,考虑一个浮点数\(a\),将其转换为定点数的操作为:一:计算\(b=a\times2^{F}\);二:将\(b\)化为整数\(^*\);三:用二进制将\(b\)表示成\(c\);四:用\(N\)位二进制数表示\(c\)成\(......
  • 洛谷P3396 哈希冲突
    根号分治模板题#include<iostream>#include<stdio.h>#include<algorithm>#include<cstring>#include<cmath>#defineRED"\033[0;32;31m"#defineNONE"\033[m"#defineR(x)x=read()#defineFor(i,j,n)for......
  • 三大操作之--flush操作
    Memstore是HBase框架中非常重要的组成部分之一,是HBase能够实现高性能随机读写至关重要的一环。深入理解Memstore的工作原理、运行机制以及相关配置,对hbase集群管理、性能调优都有着非常重要的帮助。一、Memstore概述HBase中,Region是集群节点上最小的数据服务单元,用户数据表......
  • 调度器统计 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/scheduler/sched-stats.html调度器统计版本15的schedstats删除了一些sched_yield的计数器:yld_exp_empty、yld_act_empty和yld_both_empty。除此之外,它与版本14完全相同。版本14的schedstats包括对sched_domains的支持,......
  • Kilikilinode2
    自做网页2(优化,补充)前言之前做的网页还有许多需要优化的地方,比如用户登录退出,认证方式.....等等。下面一个一个来优化一下,下面只做主要代码目录自做网页2(优化,补充)1.注册用户优化2.登录页面优化3.首页头像的优化随机显示头像和退出功能4.试下使用B站的嵌入代码,再加个背景音乐......