3.1 Region寻址、分裂与落点迁移


文档摘要

3.1 Region 寻址、分裂与落点迁移 本节摘要:Region 是 HBase 按行键区间切分的分布式与负载均衡单位。本节讲 Region 的精确定义、建表时的预分区、增长到阈值后的自动分裂过程、Master 的迁移与均衡,以及这一切对客户端"落点判断"的影响——行键不变,落点常变。 Region 到底是什么 把 1.2 与 1.3 的结论组装起来:一张表按行键字典序切成若干左闭右开的区间,每个区间就是一个 Region,形如 ;首尾 Region 的边界是负无穷与正无穷。Region 内按列族分 Store(2.2 节),Store 下是 MemStore 加一组 HFile。三个"单位"再对齐一次: 行键:数据的逻辑地址;

3.1 Region 寻址、分裂与落点迁移

本节摘要:Region 是 HBase 按行键区间切分的分布式与负载均衡单位。本节讲 Region 的精确定义、建表时的预分区、增长到阈值后的自动分裂过程、Master 的迁移与均衡,以及这一切对客户端"落点判断"的影响——行键不变,落点常变。

Region 到底是什么

把 1.2 与 1.3 的结论组装起来:一张表按行键字典序切成若干左闭右开的区间,每个区间就是一个 Region,形如 [起始键, 结束键);首尾 Region 的边界是负无穷与正无穷。Region 内按列族分 Store(2.2 节),Store 下是 MemStore 加一组 HFile。三个"单位"再对齐一次:

  • 行键:数据的逻辑地址;
  • Region:行键空间的物理切片,数据分布、分裂、迁移、均衡都以它为单位;
  • RegionServer:进程,承载若干 Region,一台机器的负载约等于它所持 Region 的负载之和。

Meta 表里每个 Region 一行,记录区间边界与宿主机(1.3 节)。一行数据的落点 = 它的行键落在哪个区间 + 那个区间此刻挂在哪台 RegionServer。后半句是动态的,本节剩下的篇幅都在讲这个"动态"。

预分区:建表时的第一刀

新表默认只有 1 个 Region,所有写入先挤进同一台机器,直到它大到分裂——冷启动阶段的热点不可避免,高峰建表甚至会直接把单节点打挂。工程上标准做法是建表即预分区

hbase:040:0> create 'orders', {NAME => 'cf', VERSIONS => 5}, hbase:041:1* SPLITS => ['1000', '2000', '3000', '4000', '5000', '6000', '7000', '8000', '9000']

SPLITS 数组给出分界键,得到 10 个 Region,建表后被 Master 尽量摊到不同 RegionServer。用 list_region 'orders' 验证:

hbase:042:0> list_region 'orders' SERVER | REGION_NAME | START_KEY | END_KEY vm1 | orders,,1724... | | 1000 vm2 | orders,1000,1724.. | 1000 | 2000 vm3 | orders,2000,1724.. | 2000 | 3000 ... | ... 10 row(s)

分界键怎么选?答案是必须与 RowKey 设计联动(第 5 章的主战场):行键若以反转用户号打头,分界键就按反转后的哈希空间均匀切;行键若带时间戳前缀,切分界等于按时间切。先定 RowKey 再定预分区,顺序反了白干。

也有偷懒的均匀哈希法:行键第一位用 00–ff 的十六进制前缀(加盐,见 5.1 节),预分区分界取 10, 20, 30 ... f0,与数据分布天然对齐。

自动分裂:Region 的成人礼

Region 增长到阈值就自动一分为二。相关参数(列族级):

参数 默认 含义
hbase.hregion.max.filesize 10 GB Region 内最大 Store 文件达到即触发分裂
hbase.regionserver.region.split.policy IncreasingToUpperRegionSplitPolicy 策略:随 Region 数增大提高触发门槛

分裂的过程(以 2.x 為例)分四步:

  1. 选分裂点:通常取 Region 中间行键(数据量中位点);
  2. 创建女儿 Region:在 HDFS 上生成两个新目录,父 Region 的 HFile 不复制,而是以"引用文件"形式指向父文件(reference file 只记偏移区间,读时按需截取);
  3. 注册与上线:Meta 表写入两个新行,Master 把女儿 Region 分配到目标 RegionServer(可能就是本机);
  4. 异步收尾:后台把引用文件重写成独立 HFile,完成后父 Region 下线删除。

整个过程对客户端的表现是:分裂瞬间到 Meta 更新完成之间,请求可能打到旧地址,收到"Region 已迁移"类异常,客户端 SDK 自动重查 Meta 并重试——业务无感,但会有几毫秒到几十毫秒的毛刺。这就是 1.3 节埋的"寻址缓存失效重查"的触发场景之一。

⚠️ 常见坑:高峰期大量 Region 同时触发自动分裂(比如整点批量导入),毛刺叠加成抖动。生产上常见做法:关闭自动分裂,改在低峰定时手动 split(策略与利弊在 3.2 节 Compaction 一并讨论)。

迁移与均衡:落点的主动漂移

分裂之外,Master 还有两个搬动 Region 的动机:

负载均衡。 Master 周期性(默认每 5 分钟)检查各 RegionServer 的 Region 数与负载,把最闲机器上的 Region 挪到最忙机器的对偶操作。迁移的过程是"先卸载(下线 Region、Flush MemStore)再在目标机打开",期间该 Region 短暂不可写。

人工调度。 运维命令:

hbase:043:0> move 'ENCODED => <region-hash>', 'vm3,16020,1724055' hbase:044:0> split 'orders,,1724055....', '5500' -- 指定分裂点手动分裂 hbase:045:0> merge_region 'hashA', 'hashB', true -- 合并两个相邻小 Region

新节点上线、热点治理、例行维护,都靠这三条命令。注意 move 的第二个参数是目标 RegionServer 的 服务器名,端口,启动时间戳 三段式,从 Web UI 复制最稳。

落点的动态计算:把全册暗线写成一个函数

把 1.3 节寻址与本节内容合起来,行键 k 的落点可以写成:

// 伪代码:客户端视角的落点计算 RegionInfo r = metaCache.lookup("orders", k); // 1 字典序落在哪个区间 ServerName s = r.getServer(); // 2 该区间当前宿主 if (write(k).fails()) { // 3 失败说明缓存过期 metaCache.refresh("orders", k); // 重查 Meta retry(); // SDK 自动完成 }

同一个行键,昨天在 vm1、分裂后到 vm2、均衡后到 vm3——数据没动(HFile 还在 HDFS 原地),动的是"谁负责服务它"。Region 迁移搬的是服务责任与少量元数据,不是海量数据本身,这是 HBase 均衡操作秒级完成的原因。

💡 关键直觉:判断"这行数据在哪台机器"要过两道字典序比较:行键 vs Region 边界、Region vs 宿主机映射。第二道随时会变,所以一切落点结论都要加时间戳。

本节要点回顾

  • Region 是切分与均衡的单位:左闭右开的行键区间,Meta 表记录边界与宿主;
  • 预分区防冷启动热点:分界键必须与 RowKey 设计联动,先定键再切刀;
  • 分裂四步:选中点、引用文件轻量分裂、上线、异步重写,客户端自动重寻址;
  • 迁移搬责任不搬数据:HFile 留在 HDFS,秒级完成,落点漂移对业务近乎透明;
  • 三大运维命令:move、split、merge_region,对应均衡、扩容、小 Region 收编。

Region 边界讲完了。Region 内部的 StoreFile 却越积越多,3.2 节看 Compaction 怎么收拾这堆碎片。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U