【HBase】HBase 自动拆分和预分区

文章目录一、Region 自动拆分二、Region 自动拆分策略2.1、ConstantSizeRegionSplitPolicy2.2、IncreasingToUpperBoundRegionSplitPolicy2.3、SteppingSplitPolicy2.4、KeyPrefixRegionSplitPolicy2.5、DelimitedKeyPrefixRegionSplitPolicy...
摘要由CSDN通过智能技术生成

一、Region 自动拆分

HBase 中,表会被划分为1…n 个 Region,被托管在 RegionServer 中。

Region 二个重要的属性:StartKey 与 EndKey 表示这个 Region 维护的 RowKey 范围,当读/写数据时,如果 RowKey 落在某个 start-end key 范围内,那么就会定位到目标region并且读/写到相关的数据。

默认,HBase 在创建表的时候,会自动为表分配一个 Region,正处于混沌时期,start-end key 无边界,所有 RowKey 都往这个 Region里分配。

当数据越来越多,Region 的 size 越来越大时,达到默认的阈值时(根据不同的拆分策略有不同的阈值),HBase 中该 Region 将会进行 split,会找到一个 MidKey 将 Region 一分为二,成为 2 个 Region。而 MidKey 则为这二个 Region 的临界,左为 N 无下界,右为 M 无上界。< MidKey 被分配到 N 区,> MidKey 则会被分配到 M 区。

随着数据量进一步扩大,分裂的两个 Region 达到临界后将重复前面的过程,分裂出更多的 Region。

二、Region 自动拆分策略

Region 的分割操作是不可见的,Master 不会参与其中。RegionServer 拆分 Region的步骤是:先将该 Region 下线,然后拆分,将其子 Region 加入到 META 元信息中,再将他们加入到原本的 RegionServer 中,最后汇报 Master。

执行 split 的线程是 CompactSplitThread。

在 2.0.5 版本中,HBase 提供了 7 种自动拆分策略:

他们之间的继承关系如下:

有三种配置方法:

  • 在 hbase-site.xml 中配置,例如:

    <property> 
      <name>hbase.regionserver.region.split.policy</name> 
      <value>org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy</value> 
    </property>
    
  • 在 HBase Configuration中配置:

    private static Configuration conf = HBaseConfiguration.create();
    conf.set("hbase.regionserver.region.split.policy", "org.apache.hadoop.hbase.regionserver.SteppingSplitPolicy");
    
  • 在创建表的时候配置:Region 的拆分策略需要根据表的属性来合理的配置, 所以在建表的时候不建议用前两种方式配置,而是针对不同的表设置不同的策略,每种策略在建表时具体使用在解释每种策略的时候说明。

2.1、ConstantSizeRegionSplitPolicy

0.94.0 之前的默认拆分策略,这种策略非常简单,只要 Region 中的任何一个 StoreFile 的大小达到了hbase.hregion.max.filesize 所定义的大小,就进行拆分。

1)相关参数:

hbase.hregion.max.filesize

  • default: 10737418240 (10GB)
  • description: 当一个 Region 的任何一个 StoreFile 容量达到这个配置定义的大小后,就会拆分 Region

2)部分源码

拆分的阈值大小可在创建表的时候设置,如果没有设置,就取hbase.hregion.max.filesize 这个配置定义的值,如果这个配置也没有定义,取默认值 10G。

  @Override
  protected void configureForRegion(HRegion region) {
   
    super.configureForRegion(region);
    Configuration conf = getConf();
    TableDescriptor desc = region.getTableDescriptor();
    if (desc != null) {
   
      // 如果用户在建表时指定了该表的单个Region的上限, 取用户定义的这个值
      this.desiredMaxFileSize = desc.getMaxFileSize();
    }
    if (this.desiredMaxFileSize <= 0) {
   
      // 如果用户没有定义, 取'hbase.hregion.max.filesize'这个配置定义的值, 如果这个配置没有定义, 取默认值 10G
      this.desiredMaxFileSize = conf.getLong(HConstants.HREGION_MAX_FILESIZE,
        HConstants.DEFAULT_MAX_FILE_SIZE);
    }
    ...
  }

  // 判断是否进行拆分
  @Override
  protected boolean shouldSplit() {
   
    boolean force = region.shouldForceSplit();
    boolean foundABigStore = false;

    for (HStore store : region.getStores()) {
   
      // If any of the stores are unable to split (eg they contain reference files)
      // then don't split
      if ((!store.canSplit())) {
   
        return false;
      }

      // Mark if any store is big enough
      if (store.getSize() > desiredMaxFileSize) {
   
        foundABigStore = true;
      }
    }

    return foundABigStore || force;
  }

3)拆分效果:

经过这种策略的拆分后,Region 的大小是均匀的,例如一个 10G 的Region,拆分为两个 Region 后,这两个新的 Region 的大小是相差不大的,理想状态是每个都是5G。

**ConstantSizeRegionSplitPolicy **切分策略对于大表和小表没有明显的区分,阈值(hbase.hregion.max.filesize):

  • 设置较大对大表比较友好,但是小表就有可能不会触发分裂,极端情况下可能就1个,这对业务来说并不是什么好事;
  • 设置较小则对小表友好,但大表就会在整个集群产生大量的 Region,这对于集群的管理、资源使用、failover 来说都不是一件好事。

4)创建表时配置:

Connection conn = ConnectionFactory.createConnection(conf);
// 创建一个数据库管理员
Admin admin = conn.getAdmin();
TableName tn = TableName.valueOf(tableName);
// 新建一个表描述,指定拆分策略和最大 StoreFile Size
TableDescriptorBuilder tableBuilder =
    TableDescriptorBuilder.newBuilder(tn)
    .setRegionSplitPolicyClassName(ConstantSizeRegionSplitPolicy.class.getName())
    .setMaxFileSize(1048576000);
// 在表描述里添加列族
for (String columnFamily : columnFamilys) {
   
    tableBuilder.setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(columnFamily)).build());
}
// 根据配置好的表描述建表
admin.createTable(tableBuilder.build());

2.2、IncreasingToUpperBoundRegionSplitPolicy

该策略继承自 ConstantSizeRegionSplitPolicy,是 0.94.0 到 2.0.0 版本的默认策略,其优化了原来 ConstantSizeRegionSplitPolicy 只是单一按照 Region 文件大小的拆分策略,增加了对当前表的分片数作为判断因子。当Region中某个 Store Size 达到 sizeToCheck 阀值时进行拆分,sizeToCheck 计算如下:

protected long getSizeToCheck(final int tableRegionsCount) {
   
    // safety check for 100 to avoid numerical overflow in extreme cases
    return tableRegionsCount == 0 || tableRegionsCount > 100
               ? getDesiredMaxFileSize()
               : Math.min(getDesiredMaxFileSize(),
                          initialSize * tableRegionsCount * tableRegionsCount * tableRegionsCount);
  }

如果表的分片数为 0 或者大于 100,则切分大小还是以设置的单一 Region 文件大小为标准。如果分片数在 1~99 之间,则由 min(单一 Region 大小, Region 增加策略的初始化大小 * 当前 Table Region 数的3次方) 决定

Region 增加策略的初始化大小计算如下:

protected void configureForRegion(HRegion region) {
   
  super.configureForRegion(region);
  Configuration conf = getConf();
  initialSize = conf.getLong("hbase.increasing.policy.initial.size", -1);
  if (initialSize > 0) {
   
    return;
  }
  TableDescriptor desc = region.getTableDescriptor();
  if (desc != null
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HBase 中,分区是一个很重要的概念,它可以提高 HBase 的性能和可伸缩性。分区是指在创建 HBase 表时,手动指定表的分区键,以便将数据分布到多个 Region 中。分区的目的是让数据分布均匀,避免某个 Region 过大而导致负载不均衡的情况。 分区的设计需要考虑以下几个因素: 1. 数据的访问模式:首先需要了解数据的访问模式,比如是否是范围查询、随机查询等,以便根据不同的访问模式来设计分区。 2. 数据的分布情况:需要了解数据的分布情况,比如数据的热点区域、数据的更新频率等,以便根据不同的分布情况来设计分区。 3. 期的数据量:需要估未来的数据量,以便根据数据量来设计分区。 4. 集群的硬件配置:需要了解集群的硬件配置,比如服务器的数量、内存大小、磁盘容量等,以便根据硬件配置来设计分区。 在设计分区时,可以采用以下几种策略: 1. 均匀分区:将表的分区键分成相等的若干部分,每个分区大小相等。 2. 范围分区:根据数据的范围来划分分区,比如按照时间范围来划分分区。 3. 哈希分区:根据分区键的哈希值来划分分区,可以确保数据分布均匀。 4. 混合分区:可以将多种分区策略组合起来使用,以便充分利用各种策略的优点。 需要注意的是,分区的设计需要根据实际情况进行调整和优化,以便达到最佳的性能和可伸缩性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值