更新时间:2026-08-19 GMT+08:00
分享

HBase应用开发建议

不建议调用Admin的closeRegion方法关闭一个Region

Admin中,提供了关闭一个Region的接口:

public void closeRegion(final String regionname, final String serverName)

通过该方法关闭一个Region,HBase Client端会直接发RPC请求到Region所在的RegionServer上,整个流程对Master而言,是不感知的。也就是说,尽管RegionServer关闭了这个Region,但是,在Master侧,还以为该Region是在该RegionServer上面打开的。假如,在执行Balance的时候,Master计算出恰好要转移这个Region,那么,这个Region将无法被关闭,本次转移操作将无法完成(关于这个问题,在当前的HBase版本中的处理的确还欠缺妥当)。

因此,暂时不建议使用该方法关闭一个Region。

采用PutList模式写数据

Table类中提供了两种写数据的接口:

  1. public void put(final Put put) throws IOException
  2. public void put(final List<Put> puts) throws IOException

第1种方法较之第2种方法,在性能上有明显的弱势。因此,写数据时应该采用第2种方法。

Scan时指定StartKey和StopKey

一个有确切范围的Scan,在性能上会带来较大的好处。

代码示例:

Scan scan = new Scan();
scan.addColumn(Bytes.toBytes("familyname"),Bytes.toBytes("columnname"));
scan.setStartRow( Bytes.toBytes("rowA")); // 假设起始Key为rowA
scan.setStopRow( Bytes.toBytes("rowB")); // 假设结束Key为rowB
for(Result result : demoTable.getScanner(scan)) {
// process Result instance
}

不要关闭WAL

WAL是Write-Ahead-Log的简称,是指数据在入库之前,首先会写入到日志文件中,借此来确保数据的安全性。

WAL功能默认是开启的,但是,在Put类中提供了关闭WAL功能的接口:

public void setWriteToWAL(boolean write)

因此,不建议调用该方法将WAL关闭(即将writeToWAL设置为False),因为可能会造成最近1秒(该值由RegionServer端的配置参数“hbase.regionserver.optionallogflushinterval”决定)内的数据丢失。但如果在实际应用中,对写入的速率要求很高,并且可以容忍丢失最近1秒内的数据的话,可以将该功能关闭。

创建一张表或Scan时设定blockcache为true

HBase客户端建表和scan时,设置blockcache=true。需要根据具体的应用需求来设定它的值,这取决于有些数据是否会被反复的查询到,如果存在较多的重复记录,将这个值设置为true可以提升效率,否则,建议关闭。

建议按默认配置,默认就是true,只要不强制设置成false就可以,例如:

HColumnDescriptor fieldADesc = new HColumnDescriptor("value".getBytes());
fieldADesc.setBlockCacheEnabled(false);

HBase不支持条件查询和Order By等查询方法,存储按照字典排序,读取只支持RowKey扫描

设计时应避免HBase随机查找、排序的应用场景。

业务表设计建议

  1. 预分Region,使Region分布均匀,提高并发
  2. 避免过多的热点Region。根据应用场景,可考虑将时间因素引入RowKey。
  3. 同时访问的数据尽量连续存储。同时读取的数据相邻存储;同时读取的数据存放在同一行;同时读取的数据存放在同一cell。
  4. 查询频繁属性放在RowKey前面部分。RowKey的设计在排序上必须与主要的查询条件契合。
  5. 离散度较好的属性作为RowKey组成部分。分析数据离散度特点以及查询场景,综合各种场景进行设计。
  6. 存储冗余信息,提高检索性能。使用二级索引,适应更多查询场景。
  7. 利用过期时间、版本个数设置等操作,让表能自动清除过期数据。

在HBase中,一直在繁忙写数据的Region被称为热点Region。

HBase客户端超时配置建议

HBase客户端相关超时配置参数如下:

  • hbase.rpc.timeout:表示RPC调用的超时时间,单位为毫秒,默认值为60000(60秒),用于控制单次RPC调用的最大耗时。
  • hbase.client.scanner.timeout.period:Scanner定义扫描操作的超时时间,单位为毫秒,默认值为360000(360秒)。如果在此时间内没有数据返回,则认为超时。
  • hbase.client.operation.timeout:客户端操作超时时间,默认值为120000毫秒(2分钟),包括一次完整的客户端操作(例如Get、Put、Delete等)。
  • hbase.client.retries.number:最大重试次数,用于表示所有可重试操作所支持的最大重试次数。

客户端配置超时参数值时需要考虑以下条件,保证客户端配置的总超时时间可覆盖重试操作:

hbase.client.operation.timeout > hbase.rpc.timeout * hbase.client.retries.number

业务对请求时延有要求时,可适当调整上述配置,建议“hbase.rpc.timeout” 值不小于5秒,重试次数不少于5次,以保证业务的稳定性。

HBase建表预分区

预分区与不预分区HBase数据表之间的区别

维度

不预分区

预分区

初始状态

建表后只有1个Region,所有写入操作集中到一台机器。

建表即有多个Region,写入操作均匀分布。

Region Split

数据增长触发自动Split,引发数据迁移和I/O风暴。

避免自动Split带来的性能抖动。

冷启动性能

初始阶段写入性能极差。

初始阶段就具备水平扩展能力。

运维复杂度

需要频繁处理热点和Split告警。

Region分布稳定,运维成本低。

预分区核心概念

                预分区边界
 Region 1        Region 2        Region 3
[  , "1a")      ["1a", "3c")    ["3c",   )
   ↓               ↓               ↓
RegionServer A  RegionServer B  RegionServer C
  • 分区边界(Split Key):定义每个Region的RowKey范围。
  • Region数量:由分区边界决定,边界数 = Region数量 - 1。
  • 数据路由:RowKey根据字典序落入对应Region。

预分区策略

  • 基于HexStringSplit预分区

    适用场景:适用于RowKey前缀为hex散列值(0~9, a~f)的场景。

    建表语句

    方式一:手动指定16进制分区分界点

    create 'my_table', 'cf', SPLITS => [
      '1', '2', '3', '4', '5', '6', '7', '8', '9',
      'a', 'b', 'c', 'd', 'e', 'f'
    ]

    方式二:使用HBase Shell内置分割器

    create 'my_table', 'cf', {NUMREGIONS => 16, SPLITALGO => 'HexStringSplit'}

    分区分布

    Region

    RowKey范围

    Region 1

    [ , 1)

    Region 2

    [1, 2)

    ...

    ...

    Region 16

    [f, )

  • 基于业务数据量估算预分区

    适用场景:适用于数据量可预估,需要更精细分区控制的场景。

    计算步骤

    1. 预估总数据量(行数和存储量)。
    2. 确定单Region目标大小。
    3. 计算预分区数量。

      预分区计算公式:Region数量 = 预估总数据量(GB) / 单Region目标大小(GB)。

      在预分区时需要考虑未来数据增长:

      • 预分区数量按1.5~2倍当前数据量计算。
      • 初始Region可适当偏小(5~7GB),为数据增长留出空间。
      • 设置合理的“MAX_FILESIZE”或集群级别设置合理的Region分裂大小,控制自动Split阈值。
      • 可以根据业务所需合理地调整split策略。

      Region分裂相关配置

      参数名

      参数说明

      默认值

      hbase.hregion.max.filesize

      HStoreFile的最大大小(单位:字节)。如果任何一个列族的HStoreFile超过此参数值,托管的HRegion将会被拆分为两个。

      10G

      hbase.regionserver.region.split.policy

      定义split策略。目前可用的split策略有ConstantSizeRegionSplitPolicy、DisabledRegionSplitPolicy、DelimitedKeyPrefixRegionSplitPolicy、KeyPrefixRegionSplitPolicy等。

      org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy

    4. 根据散列前缀范围生成分区边界。
  • 基于时间范围预分区

    适用场景:适用于RowKey包含时间前缀,且查询模式以时间范围为主的场景。

    时间前缀容易产生写热点(当前时间的数据集中写入),所以仅在数据写入量可控或已通过其他方式打散的场景使用。

    按月分区注意事项

    • 不同月份的数据量可能差异较大,导致Region大小不均。
    • 需定期评估是否需要手动Split大Region或Merge小Region。
    预分区策略选择

    场景

    推荐策略

    原因

    RowKey前缀为hex散列

    HexStringSplit

    天然对齐16进制前缀,分区均匀。

    数据量可预估

    业务数据量估算

    精确控制Region大小,避免过小或过大。

    按时间查询为主

    时间范围预分区

    Scan效率高,但需注意写热点。

    数据分布不可预知

    UniformSplit

    字节空间均匀切分,通用性强。

相关文档