技术篇-深入解读 HBase2.0 新功能之 AssignmentManagerV2

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
云数据库 Redis 版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 1.背景 AssignmentManager 模块是 HBase 中一个非常重要的模块,Assignment Manager (之后简称 AM)负责了 HBase 中所有 region 的 Assign,UnAssign,以及 split/merge 过程中 region 状态变化的管理等等。

1.背景

AssignmentManager 模块是 HBase 中一个非常重要的模块,Assignment Manager (之后简称 AM)负责了 HBase 中所有 region 的 Assign,UnAssign,以及 split/merge 过程中 region 状态变化的管理等等。在 HBase-0.90 之前,AM 的状 态全部存在内存中,自从 HBASE-2485 之后,AM 把状态持久化到了 Zookeeper 上。在此基础上,社区对 AM 又修复了大量的 bug 和优化(见此文章),最终形成了用在 HBase-1.x 版本上的这个 AM。

2.老 Assignment Mananger 的问题

相信深度使用过 HBase 的人一般都会被 Region RIT 的状态困扰过,长时间的 region in transition 状态简直令人抓狂。

_2019_01_10_2_17_55

除了一些确实是由于 Region 无法被 RegionServer open 的 case,大部分的 RIT, 都是 AM 本身的问题引起的。总结一下 HBase-1.x 版本中 AM 的问题,主要有以下几点:

3.region 状态变化复杂

_2019_01_10_2_19_08

这张图很好地展示了 region 在 open 过程中参与的组件和状态变化。可以看到, 多达 7 个组件会参与 region 状态的变化。并且在 region open 的过程中多达 20 多个步骤!越复杂的逻辑意味着越容易出 bug

4.region 状态多处缓存

region 的状态会缓存在多个地方,Master 中 RegionStates 会保存 Region 的状 态,Meta 表中会保存 region 的状态,Zookeeper 上也会保存 region 的状态,要保持这三者完全同步是一件很困难的事情。同时,Master 和 RegionServer 都会 修改 Meta 表的状态和 Zookeeper 的状态,非常容易导致状态的混乱。如果出现 不一致,到底以哪里的状态为准?每一个 region 的 transition 流程都是各自为政, 各自有各自的处理方法

5.重度依赖 Zookeeper

在老的 AM 中,region 状态的通知完全通过 Zookeeper。比如说 RegionServer 打开了一个 region,它会在 Zookeeper 把这个 region 的 RIT 节点改成 OPEN 状态, 而不去直接通知 Master。Master 会在 Zookeeper 上 watch 这个 RIT 节点,通过 Zookeeper 的通知机制来通知 Master 这个 region 已经发生变化。Master 再根据 Zookeeper 上读取出来的新状态进行一定的操作。严重依赖 Zookeeper 的通知机制导致了 region 的上线/下线的速度存在了一定的瓶颈。特别是在 region 比较多 的时候,Zookeeper 的通知会出现严重的滞后现象。

正是这些问题的存在,导致 AM 的问题频发。我本人就 fix 过多个 AM 导致 region 无法 open 的 issue。比如说这三个相互关联的“连环”case:HBASE-17264,HBASE- 17265,HBASE-17275。

6.Assignment Mananger V2

面对这些问题的存在,社区也在不断尝试解决这些问题,特别是当 region 的规模达到 100w 级别的时候,AM 成为了一个严重的瓶颈。HBASE-11059 中提出的 ZK-less Region Assignment 就是一个非常好的改良设计。在这个设计中,AM 完 全摆脱了 Zookeeper 的限制,在测试中,zk-less 的 assign 比 zk 的 assign 快了一个数量级!

_2019_01_10_2_22_11

但是在这个设计中,它摒弃了 Zookeeper 这个持久化的存储,一些 region transition 过程中的中间状态无法被保存。因此,在此基础上,社区又更进了一步,提出了 Assignment Mananger V2 在这个方案。在这个方案中,仍然摒弃了
Zookeeper 参与 Assignment 的整个过程。但是,它引入了 ProcedureV2 这个持久化存储来保存 Region transition 中的各个状态,保证在 master 重启时,之前的 assing/unassign,split 等任务能够从中断点重新执行。具体的来说,AMv2 方案中,主要的改进有以下几点:

7.Procedure V2

关于 Procedure V2,我之后将独立写文章介绍。这里,我只大概介绍下 ProcedureV2 和引入它所带来的价值。

我们知道,Master 中会有许多复杂的管理工作,比如说建表,region 的transition。 这些工作往往涉及到非常多的步骤,如果 master 在做中间某个步骤的时候宕机了,这个任务就会永远停留在了中间状态(RIT 因为之前有 Zookeeper 做持久化因此会继续从某个状态开始执行)。比如说在 enable/disable table 时,如果 master宕机了,可能表就停留在了 enabling/disabling 状态。需要一些外部的手段进行恢复。那么从本质上来说,ProcedureV2 提供了一个持久化的手段(通过 ProcedureWAL,一种类似 RegionServer 中 WAL 的日志持久化到 HDFS 上),使 master 在宕机后能够继续之前未完成的任务继续完成。同时,ProcedureV2 提供了非常丰富的状态转换并支持回滚执行,即使执行到某一个步骤出错,master 也可以按照用户的逻辑对之前的步骤进行回滚。比如建表到某一个步骤失败了,而之前已经在 HDFS 中创建了一些新 region 的文件夹,那么 ProcedureV2 在rollback的时候,可以把这些残留删除掉。

_2019_01_10_2_30_00

Procedure 中提供了两种 Procedure 框架,顺序执行和状态机,同时支持在执行过程中插入 subProcedure,从而能够支持非常丰富的执行流程。在 AMv2 中,所有的 Assign,UnAssign,TableCreate 等等流程,都是基于 Procedure 实现的。

_2019_01_10_2_30_55

8.去除 Zookeeper 依赖

有了 Procedure V2 之后,所有的状态都可以持久化在 Procedure 中,Procedure 中每次的状态变化,都能够持久化到 ProcedureWAL 中,因此数据不会丢失,宕 机后也能恢复。同时,AMv2 中 region 的状态扭转(OPENING,OPEN,CLOSING, CLOSE 等)都会由 Master 记录在 Meta 表中,不需要 Zookeeper 做持久化。再者,之前的 AM 使用的 Zookeeper watch 机制通知 master region 状态的改变, 而现在每当 RegionServer Open 或者 close 一个 region 后,都会直接发送 RPC 给 master 汇报,因此也不需要 Zookeeper 来做状态的通知。综合以上原因,Zookeeper 已经在 AMv2 中没有了存在的必要。

9.减少状态冲突的可能性

之前我说过,在之前的 AM 中,region的状态会同时存在于 meta 表,Zookeeper 和 master 的内存状态。同时 Master 和 regionserver 都会去修改 Zookeeper 和 meta 表,维护状态统一的代价非常高,非常容易出 bug。而在 AMv2 中,只有 master 才能去修改 meta 表。并在 region 整个 transition 中做为一个“权威”存在, 如果 regionserver 汇报上来的 region 状态与 master 看到的不一致,则 master 会 命令 RegionServer abort。Region 的状态,都以 master 内存中保存的 RegionStates 为准。
除了上述这些优化,AMv2 中还有许多其他的优化。比如说 AMv2 依赖 Procedure V2 提供的一套 locking 机制,保证了对于一个实体,如一张表,一个 region 或 者一个 RegionServer 同一时刻只有一个 Procedure 在执行。同时,在需要往 RegionServer 发送命令,如发送 open,close 等命令时,AMv2 实现了一个 RemoteProcedureDispatcher 来对这些请求做 batch,批量把对应服务器的指令
一起发送等等。在代码结构上,之前处理相应 region 状态的代码散落在 AssignmentManager 这个类的各个地方,而在 AMv2 中,每个对应的操作,都有 对 应 的 Procedure 实 现 , 如 AssignProcedure , DisableTableProcedure , SplitTableRegionProcedure 等等。这样下来,使 AssignmentManager 这个之前 杂乱的类变的清晰简单,代码量从之前的 4000 多行减到了 2000 行左右。

10.AssignProcedure

AMv2 中有太多的 Procedure 对应各种不同的 transition,这里不去详细介绍每个 Procedure 的操作。我将以 AssignProcedure 为例,讲解一下在 AMv2 中,一个 region 是怎么 assign 给一个 RegionServer,并在对应的 RS 上 Open 的。

_2019_01_10_2_33_47

AssignProcedure 是一个基于 Procedure 实现的状态机。它拥有 3 个状态:

  1. REGION_TRANSITION_QUEUE: Assign 开始时的状态。在这个状态时, Procedure 会对 region 状态做一些改变和存储,并丢到 AssignmentManager 的 assign queue 中。对于单独 region 的 assign,AssignmentManager 会把 他们 group 起来,再通过 LoadBalancer 分配相应的服务器。当这一步骤完 成后,Procedure 会把自己标为 REGION_TRANSITION_DISPATCH,然后看是否已经分配服务器,如果还没有被分配服务器的话,则会停止继续执行,等待 被唤醒。
  1. REGION_TRANSITION_DISPATCH: 当 AssignmentManager 为这个 region 分配 好服务器时,Procedure 就会被唤醒。或者Procedure 在执行完REGION_TRANSITION_QUEUE 状态时 master 宕机,Procedure 被恢复后,也会进入此步骤执行。所以在此步骤下,Procedure 会先检查一下是否分配好了 服务器,如果没有,则把状态转移回 REGION_TRANSITION_QUEUE,否则的话, 则把这个 region 交给 RemoteProcedureDispatcher,发送 RPC 给对应的 RegionServer 来 open 这个 region。同样的,RemoteProcedureDispatcher 也会对相应的指令做一个 batch,批量把一批 region open 的命令发送给某 一台服务器。当命令发送完成之后,Procedure 又会进入休眠状态,等待 RegionServer 成功 OPen 这个 region 后,唤醒这个 Procedure
  2. REGION_TRANSITION_FINISH: 当有 RegionServer 汇报了此 region 被打开后,会把 Procedure 的状态置为此状态,并唤醒 Procedure 执行。此时, AssignProcedure 会做一些状态改变的工作,并修改 meta 表,把 meta 表中这个region的位置指向对应的RegionServer。至此,region assign的工 作全部完成。
    AMv2 中提供了一个 Web 页面(Master 页面中的‘Procedures&Locks’链接)来展 示当前正在执行的 Procedure 和持有的锁。其实通过 log,我们也可以看到 Assign 的整个过程。假设,一台 server 宕机,此时 master 会产生一个ServerCrashProcedure 来处理,在这个 Procedure 中,会做一系列的工作,比如 WAL 的 restore。当这些前置的工作做完后,就会开始 assign 之前在宕掉服务器 上 的 region , 比 如 56f985a727afe80a184dac75fbf6860c 。 此时会在 ServerCrashProcedure 产生一系列的子任务:

_2019_01_10_2_55_17

可以看到,ServerCrashProcedure 的 pid(Procedure ID)为 1178,在此 Procedure 中产生的 assign 56f985a727afe80a184dac75fbf6860c 这个 region 的子 Procedure 的 pid 为 1179,同时他的 ppid(Parent Procedure ID)为 1178。在 AMv2 中, 通过追踪这些 ID,就非常容易把一个 region 的 transition 整个过程全部串起来。 接下来,pid=1170 这个 Procedure 开始执行,首先执行的是 REGION_TRANSITION_QUEUE 状态的逻辑,然后进入睡眠状态。

_2019_01_10_2_56_07

当 target server 被指定时,Procedure 进入 REGION_TRANSITION_DISPATCH 状态,dispatch 了 region open 的请求,同时把 meta 表中 region 的状态改成了 OPENING,然后再次进入休眠状态。

_2019_01_10_2_56_51

最后,当 RegionServer 打开了这个 region 后,会发 RPC 通知 master,那么在通知过程中,这个 Procedure 再次被唤醒,开始执行 REGION_TRANSITION_FINISH 的逻辑,最后更新 meta 表,把这个 region 置为打开状态。

_2019_01_10_2_57_42

一路看下来,由于整个 region assign 的过程都是在 Procedure 中执行,整个过程 清晰明了,非常容易追述,也没有了 Zookeeper 一些 event 事件的干扰。

11.总结

Assignment Mananger V2 依赖 Procedure V2 实现了一套清晰明了的 region transition 机制。去除了 Zookeeper 依赖,减少了 region 状态冲突的可能性。整体上来看,代码的可读性更强,出了问题也更好查错。对于解决之前 AM 中的一 系列“顽疾”,AMv2 做了很好的尝试,也是一个非常好的方向。

AMv2 之所以能保持简洁高效的一个重要原因就是重度依赖了 Procedure V2,把 一些复杂的逻辑都转移到了 Procedure V2 中。但是这样做的问题是:一旦 ProcedureWAL 出现了损坏,或者 Procedure 本身存在 bug,这个后果就是灾难 性的。事实上在我们的测试环境中,就出现过 PRocedureWAL 损坏导致 region RIT 的情况。

另外需要注意的是,截止目前为止,HBCK 仍然无法支持 AMv2,这会导致一旦 出现问题,修复起来会比较困难。当然,新的事务还是要有一段成熟期,相信经 过一段时间的 bug 修复和完善后,我相信 AMv2 一定会完美解决之前的一些问 题,给HBase的运维上带来一些不同的体验。愿世界不再被HBase的RIT困扰 :-)。

作者:杨文龙 阿里巴巴 技术专家 HBase Committer&HBase PMC

相关实践学习
lindorm多模间数据无缝流转
展现了Lindorm多模融合能力——用kafka API写入,无缝流转在各引擎内进行数据存储和计算的实验。
云数据库HBase版使用教程
  相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情: https://cn.aliyun.com/product/hbase   ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4月前
|
存储 分布式计算 大数据
HBase分布式数据库关键技术与实战:面试经验与必备知识点解析
【4月更文挑战第9天】本文深入剖析了HBase的核心技术,包括数据模型、分布式架构、访问模式和一致性保证,并探讨了其实战应用,如大规模数据存储、实时数据分析及与Hadoop、Spark集成。同时,分享了面试经验,对比了HBase与其他数据库的差异,提出了应对挑战的解决方案,展望了HBase的未来趋势。通过Java API代码示例,帮助读者巩固理解。全面了解和掌握HBase,能为面试和实际工作中的大数据处理提供坚实基础。
219 3
|
4月前
|
Java Shell 分布式数据库
【大数据技术Hadoop+Spark】HBase数据模型、Shell操作、Java API示例程序讲解(附源码 超详细)
【大数据技术Hadoop+Spark】HBase数据模型、Shell操作、Java API示例程序讲解(附源码 超详细)
134 0
|
3月前
|
存储 大数据 分布式数据库
使用Apache HBase进行大数据存储:技术解析与实践
【6月更文挑战第7天】Apache HBase,一个基于HDFS的列式存储NoSQL数据库,提供高可靠、高性能的大数据存储。其特点是列式存储、可扩展至PB级数据、低延迟读写及多版本控制。适用场景包括大规模数据存储、实时分析、日志存储和推荐系统。实践包括集群环境搭建、数据模型设计、导入、查询及性能优化。HBase在大数据存储领域扮演关键角色,未来有望在更多领域发挥作用。
|
3月前
|
存储 SQL 分布式计算
技术心得记录:深入学习HBase架构原理
技术心得记录:深入学习HBase架构原理
|
3月前
|
存储 缓存 分布式计算
必知的技术知识:Hbase配置(伪分布式模式)
必知的技术知识:Hbase配置(伪分布式模式)
149 0
|
4月前
|
存储 分布式计算 Java
大数据存储技术(3)—— HBase分布式数据库
大数据存储技术(3)—— HBase分布式数据库
769 0
|
11月前
|
存储 分布式计算 NoSQL
|
SQL 存储 大数据
大数据技术之HBase5
大数据技术之HBase5
129 0
|
存储 SQL 缓存
大数据技术之HBase4
大数据技术之HBase4
145 0
|
存储 缓存 监控
大数据技术之HBase3
大数据技术之HBase3
234 0