讲讲 HBase 写入数据的完整流程
HBase 的数据写入流程是大数据面试中的高频考点,也是理解 HBase 基于 LSM树(Log-Structured Merge-Tree) 架构设计的核心。
HBase 的写入流程以“极速”著称,因为它将随机写转化为了顺序写日志 + 内存写。
我们可以将完整的写入流程分为三个大阶段:1. 客户端寻址路由 -> 2. RegionServer 核心写入 -> 3. 后台异步刷盘与合并。
第一阶段:客户端寻址路由 (Client Routing)
HBase 是一个分布式数据库,数据按照 RowKey 切分成多个 Region 分布在不同的 RegionServer 上。客户端在写入数据前,必须先找到这条数据应该写到哪台机器上。
- 连接 ZooKeeper:客户端首先访问 ZooKeeper,从 ZK 中获取
hbase:meta表所在的 RegionServer 的地址。
(注:hbase:meta是 HBase 的一张系统表,里面记录了所有用户表的 Region 位置信息) - 查询 Meta 表:客户端连接托管
hbase:meta表的 RegionServer,根据要写入的表名 (TableName) 和行键 (RowKey),查询出该条数据对应的目标 Region 以及托管该 Region 的目标 RegionServer 地址。 - 缓存路由信息:客户端会将这个路由信息缓存在本地。下次写入或读取同区域的数据时,直接从本地缓存获取地址,不需要再走 ZK 和 Meta 表。如果后来 Region 发生了分裂或转移导致缓存失效,客户端会收到报错,然后重新执行 1、2 步更新缓存。
第二阶段:RegionServer 核心写入 (Core Write Process)
客户端找到目标 RegionServer 后,发送 Put 请求,数据到达具体的 RegionServer。
- 获取行锁 (Row Lock):
HBase 保证行级别的原子性。在写入之前,RegionServer 会先获取对应 RowKey 的行锁,防止并发修改同一行数据导致不一致。 - 写预写日志 (WAL - Write-Ahead Log):
- 作用:防止机器宕机导致内存中的数据丢失。
- 过程:数据首先会被顺序追加写入到 HDFS 上的 WAL 文件中。因为是顺序写,所以磁盘 I/O 极快。只有当数据成功写入 WAL,才算有了持久化保障。
- 写内存 (MemStore):
- 数据写入 WAL 后,紧接着会被写入到该 Column Family(列族)对应的内存结构 MemStore 中。
- MemStore 内部采用跳表(SkipList)数据结构,数据在这里会根据
RowKey -> Column Family -> Column Qualifier -> Timestamp进行字典序排序。
- 释放行锁并返回成功:
数据写入 MemStore 完毕后,释放行锁,并向客户端返回写入成功 (ACK) 的响应。
(注意:此时数据还在内存中,尚未真正落盘为 HFile,但因为有 WAL 的存在,数据已绝对安全。正因为实际写入的是内存,HBase 的写入延迟极低。)
第三阶段:后台异步刷盘与优化 (Flush & Compaction)
随着不断写入,MemStore 中的数据越来越多,HBase 会在后台触发一系列操作,将内存数据转化为 HDFS 上的实际文件,并进行优化。
1. 内存刷写 (MemStore Flush)
当满足以下条件之一时,MemStore 中的数据会被 Flush(刷写)到 HDFS 上,形成一个新的 HFile (StoreFile):
- Region 级别:某个 MemStore 的大小达到了设定的阈值(默认 128MB)。
- RegionServer 级别:一台 RegionServer 上所有 MemStore 的总大小达到了安全水位阈值(会阻塞所有写入,直到 Flush 腾出空间)。
- WAL 级别:WAL 日志文件数量过多,为了清理旧日志,会强制 Flush。
- 时间级别:到达了设定的定期 Flush 时间(默认 1 小时)。
Flush 结束后,这部分数据在 WAL 中的记录就可以被清理了。
2. 文件合并 (Compaction)
随着多次 Flush,HDFS 上会产生越来越多的小 HFile。为了提高查询效率(读数据时需要扫描 HFile),HBase 会在后台进行 Compaction(合并)。
- Minor Compaction(小合并):将几个较小的、相邻的 HFile 合并成一个较大的 HFile。不会清理被删除或过期的数据。
- Major Compaction(大合并):将一个 Store(列族)下的所有 HFile 合并成一个巨大的 HFile。会彻底清理掉那些带有删除标记(Tombstone)、TTL 过期、或超过最大版本数限制的数据。Major Compaction 会消耗大量磁盘和网络 I/O,通常安排在业务低峰期执行。
3. 分裂 (Region Split)
当某个 Region 的所有 HFile 总大小超过了设定的阈值(默认 10GB)时,HBase 会将这个 Region 一分为二(Split)。
新的两个子 Region 可能会被 HMaster 负载均衡分配到不同的 RegionServer 上,以保证集群请求的均匀分布。
总结与核心考点(面试必背)
你可以用下面这段话作为电梯演讲(简短总结):
HBase 的写入流程首先是客户端寻址,通过 ZK 找到 Meta 表,再找到目标 RegionServer。数据到达 RegionServer 后,为了保证高性能和数据不丢失,HBase 采用了 LSM 树架构:首先顺序写 WAL 日志保证数据持久化,然后写入内存 MemStore 进行排序,随即向客户端返回成功。因此写入速度极快。当内存达到阈值时,会在后台异步 Flush 成 HFile 落盘到 HDFS。随着小文件增多,HBase 会通过 Compaction 合并文件并清理过期数据,最后在 Region 过大时进行 Split 分裂以保证负载均衡。