0%

HBase写数据过程

HBase写数据流程全解析:从请求到持久化

HBase 的写数据过程设计兼顾了 高吞吐数据可靠性,通过 “预写日志 + 内存缓存 + 异步刷盘” 的机制,在保证数据不丢失的前提下最大化写入性能。以下详细拆解写流程的每个环节,包括核心步骤、优化机制及故障恢复逻辑。

写数据核心流程概述

HBase 写操作的核心目标是 快速接收数据并确保不丢失,整体流程可概括为 “客户端请求 → 预写日志 → 内存缓存 → 异步刷盘”,具体步骤如下:

  1. 客户端向目标 RegionServer 发送写请求;
  2. RegionServer 先将数据写入预写日志(WAL/HLog),确保崩溃后可恢复;
  3. 数据写入内存缓存(MemStore),立即反馈客户端 “写成功”;
  4. 当 MemStore 达到阈值,异步刷写到磁盘(StoreFile),完成持久化;
  5. 定期合并小文件并拆分过大 Region,优化存储结构。

详细流程拆解

第一步:客户端定位目标 RegionServer

写操作前,客户端需先确定数据所属的 Region 及对应的 RegionServer,流程与读操作类似:

  • 客户端通过 ZooKeeper 获取 hbase:meta 表位置;
  • 查询 hbase:meta 表,根据 RowKey 定位目标 Region 所在的 RegionServer;
  • 客户端直接向该 RegionServer 发送写请求(携带表名、RowKey、列族:列名、值等信息)。

第二步:写入预写日志(WAL/HLog)

为防止内存数据丢失,HBase 采用 “预写日志(Write-Ahead Log,WAL)” 机制,这是数据可靠性的核心保障。

  • RegionServer 操作
    1. 接收到写请求后,RegionServer 先将数据按固定格式(包含 RowKey、列信息、时间戳、操作类型等)写入本地 HLog 文件;
    2. HLog 文件同步存储在 HDFS 上(多副本),确保即使 RegionServer 宕机,日志也不会丢失。
  • 作用:HLog 是数据的 “安全网”,当 RegionServer 崩溃且 MemStore 数据未刷盘时,可通过 HLog 重建数据。

第三步:写入内存缓存(MemStore)

数据写入 HLog 后,RegionServer 将数据写入对应 Region 的 MemStore(内存缓存):

  • MemStore 特性:每个列族(Column Family)对应一个 MemStore,数据按 RowKey 排序存储,支持高效的插入和查询;
  • 客户端反馈:数据写入 MemStore 后,RegionServer 立即向客户端返回 “写成功” 响应,无需等待刷盘,大幅降低写入延迟。

第四步:MemStore 刷盘(Flush to StoreFile)

MemStore 是内存结构,若持续写入会导致内存溢出,且存在断电丢失风险。因此 HBase 会在满足以下条件时触发 刷盘操作,将 MemStore 数据写入磁盘的 StoreFile(HFile 格式):

触发刷盘的条件
  • 大小阈值:默认当 MemStore 占用内存达到 128MB(可通过 hbase.hregion.memstore.flush.size 配置);
  • 时间阈值:若 MemStore 数据超过 1 小时未刷盘(可通过 hbase.regionserver.optionalcacheflushinterval 配置);
  • Region 级阈值:当一个 Region 中所有 MemStore 总大小达到 Region 内存上限(默认 Region 内存 = 堆内存 * 0.4 / Region 数量);
  • 手动触发:通过 flush '表名' 命令强制刷盘。
刷盘过程
  1. RegionServer 对目标 MemStore 加锁,阻止新写入(短暂阻塞,毫秒级);
  2. 将 MemStore 中的数据按 RowKey 排序后写入临时文件;
  3. 临时文件转正为 StoreFile,添加到对应 Store 的文件列表;
  4. 释放锁,删除 MemStore 中的数据,更新 HLog 标记(已刷盘的数据可从 HLog 中清理)。

第五步:StoreFile 合并(Compaction)

频繁刷盘会产生大量小 StoreFile,导致读操作需扫描多个文件,降低效率。HBase 通过 合并(Compaction) 机制将小文件合并为大文件:

合并类型
  • Minor Compaction(小合并):默认当 StoreFile 数量超过 3 个(可配置),将部分小文件合并为一个较大文件,不删除过期数据;
  • Major Compaction(大合并):默认 7 天一次(可配置),将一个 Store 中所有 StoreFile 合并为一个大文件,同时删除过期数据(如超过 TTL、版本数超限的数据)。
合并过程
  1. RegionServer 选择符合条件的 StoreFile 列表;
  2. 读取所有文件数据,按 RowKey 排序并去重(保留最新版本);
  3. 写入新的合并文件,替换原小文件;
  4. 删除旧文件,释放磁盘空间。

第六步:Region 拆分(Split)

当一个 Region 中所有 StoreFile 的总大小超过阈值(默认 10GB,可通过 hbase.hregion.max.filesize 配置),Region 会自动拆分为两个子 Region,避免单个 Region 过大导致性能下降:

  • 拆分过程
    1. 选择中间 RowKey 作为拆分点(如按文件大小均分);
    2. 生成两个子 Region([startRow, splitRow)[splitRow, endRow));
    3. HMaster 将子 Region 分配到其他 RegionServer,实现负载均衡。

数据可靠性保障:HLog 与故障恢复

HLog 是 HBase 数据不丢失的核心保障,其设计细节直接影响故障恢复能力:

HLog 存储机制

  • 物理存储:HLog 以文件形式存储在 HDFS 的 /hbase/WALs/<RegionServer> 目录,默认 3 副本,确保磁盘损坏不丢失;
  • 文件滚动:单个 HLog 文件达到阈值(默认 1GB)后自动滚动为新文件,旧文件在数据刷盘后删除;
  • 格式:每条日志记录包含 Region 信息、RowKey、列数据、时间戳等,支持按 Region 拆分恢复。

RegionServer 宕机后的恢复流程

  1. 检测故障:ZooKeeper 通过心跳机制检测到 RegionServer 宕机,通知 HMaster;
  2. 拆分 HLog:HMaster 读取宕机 RegionServer 的 HLog,按 Region 拆分日志;
  3. 分配 Region:将宕机的 Region 重新分配给其他正常的 RegionServer;
  4. 重演日志:新 RegionServer 加载 Region 后,读取对应 HLog 片段,将未刷盘的数据重新写入 MemStore 并刷盘;
  5. 恢复服务:Region 状态变为 “在线”,开始接收新请求。

写流程优化机制

1. 批量写入(Batch Put)

客户端支持将多个写请求打包为批量请求(BatchPut),减少网络往返次数,提升吞吐量:

1
2
3
4
5
6
7
8
// Java API 示例:批量写入 1000 条数据  
List<Put> puts = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
Put put = new Put(Bytes.toBytes("row" + i));
put.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("col"), Bytes.toBytes("value" + i));
puts.add(put);
}
table.put(puts); // 批量提交

2. 异步刷盘与合并

  • 刷盘和合并操作均在后台异步执行,不阻塞前端写请求;
  • 合并过程可通过配置限制 IO 带宽(hbase.hstore.compaction.throughput.lower.bound),避免影响正常读写。

3. WAL 优化

  • WAL 异步写入:通过 hbase.regionserver.wal.async 配置开启异步写 HLog,降低延迟(默认同步写入,确保可靠性);
  • WAL 压缩:对 HLog 启用压缩(如 Snappy),减少磁盘 IO 和存储空间。

流程示意图

graph TD
    A[客户端] -->|1. 发送写请求| B[目标 RegionServer]
    B -->|2. 写入预写日志WAL/HLog
同步到 HDFS 多副本| C[HLog 持久化] C -->|3. 写入内存缓存MemStore
按 RowKey 排序| D[MemStore] D -->|4. 立即反馈| A D -->|5. 触发刷盘条件?
大小/时间阈值等| E{判断} E -->|是| F[MemStore 刷盘
生成 StoreFile] E -->|否| D F -->|6. 小文件数量/大小达标?| G{判断} G -->|是| H[StoreFile 合并
Minor/Major Compaction] G -->|否| F H -->|7. Region 大小超限?| I{判断} I -->|是| J[Region 拆分
子 Region 负载均衡] I -->|否| H J -->|8. 新 Region 分配到其他 RegionServer| B

欢迎关注我的其它发布渠道