HBase 2.x核心技术

文章详细介绍了HBase2.x版本中的关键特性,包括基于Procedurev2的管理流程,提高写入性能的InMemoryCompaction机制,存储大对象的MOB功能,以及读写路径的Offheap优化,强调了异步化设计在提高系统吞吐量方面的作用。这些改进旨在解决分布式场景下的状态一致性、写放大、内存管理和延迟问题,提升HBase的稳定性和性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HBase 2.x主要包含以下核心功能:
1、基于Procedure v2重新设计了HBase的Assignment Manager和核心管理流程。通过Procedure v2,HBase能保证各核心步骤的原子性,从设计上解决了分布式场景下多状态不一致的问题。
2、实现了In Memory Compaction功能。该功能将MemStore分成若干小数据块,将多个数据块在MemStore内部做Compaction,一方面缓解了写放大的问题,另一方面降低了写路径的GC压力。
3、存储MOB数据。2.0.0版本之前对大于1MB的数据支持并不友好,因为大value场景下Compaction会加剧写放大问题,同时容易挤占HBase的BucketCache。而新版本通过把大value存储到独立的HFile中来解决这个问题,更好地满足了多样化的存储需求。
4、读写路径全链路Offheap化。在2.0版本之前,HBase只有读路径上的BucketCache可以存放Offheap,而在2.0版本中,社区实现了从RPC读请求到完成处理,最后到返回数据至客户端的全链路内存的Offheap化,从而进一步控制了GC的影响。
5、异步化设计。异步的好处是在相同线程数的情况下,提升系统的吞吐量。2.0版本中做了大量的异步化设计,例如提供了异步的客户端,采用Netty实现异步RPC,实现asyncFsWAL等。

一、Procedure功能

1, Procedure定义

一个Procedure一般由多个subtask组成,每个subtask是一些执行步骤的集合,这些执行步骤中又会依赖部分Procedure。
在这里插入图片描述
上图Procedure.0有A、B、C、G共4个subtask,而这4个subtask中的C又有1个Procedure,也就是说只有等这个Procedure执行完,C这个subtask才能算执行成功。而C中的子Procedure,又有D、E、F共3个subtask。

在这里插入图片描述
上图Procedure.0有A、B、C、D共4个subtask。其中subtask C又有Procedure.1、Procedure.2、Procedure.3共3个子Procedure。
在这里插入图片描述
建表操作可以认为是一个Procedure,它由4个subtask组成。
(1)subtask.A:用来初始化Test表在HDFS上的文件。
(2)subtask.B:在hbase:meta表中添加Test表的Region信息。
(3)subtask.C:将3个region分配到多个节点上,而每个Assign region的过程又是一个Procedure。
(4)subtask.D:最终将表状态设置为ENABLED
在明确了Procedure的结构之后,需要理解Procedure提供的两个接口:execute()和rollback(),其中execute()接口用于实现Procedure的执行逻辑,rollback()接口用于实现Procedure的回滚逻辑。这两个接口的实现需要保证幂等性。也就是说,如果x=1,执行两次increment(x)后,最终x应该等于2,而不是等于3。因为我们需要保证increment这个subtask在执行多次之后,同执行一次得到的结果完全相等。

2,Procedure执行和回滚

以建表的Procedure为例,探讨Procedure v2是如何保证整个操作的原子性的。
首先,引入Procedure Store的概念,Procedure内部的任何状态变化,或者Procedure的子Procedure状态发生变化,或者从一个subtask转移到另一个subtask,都会被持久化到HDFS中。持久化的方式也很简单,就是在Master的内存中维护一个实时的Procedure镜像,然后有任何更新都把更新顺序写入Procedure WAL日志中。由于Procedure的信息量很少,内存占用小,所以只需内存镜像加上WAL的简单实现,即可保证Procedure状态的持久性。
其次,需要理解回滚栈和调度队列的概念。回滚栈用于将Procedure的执行过程一步步记录在栈中,若要回滚,则一个个出栈依次回滚,即可保证整体任务流的原子性。调度队列指的是Procedure在调度时使用的一个双向队列,如果某个Procedure调度优先级特别高,则直接入队首;如果优先级不高,则直接入队尾。
Procedure的回滚:有了回滚栈这个状态之后,在执行任何一步发生异常需要回滚的时候,都可以按照栈中顺序依次将之前已经执行成功的subtask或者子Procedure回滚,且严格保证了回滚顺序和执行顺序相反。如果某一步回滚失败,上层设计者可以选择重试,也可以选择跳过继续重试当前任务(设计代码抛出不同类型的异常),直接回滚栈中后一步状态。
注意:Procedure的rollback()实现必须是幂等的,因此在重试的时候,即使某一步回滚多次,依然能保证状态的一致性。

3,Procedure Suspend

在执行Procedure时,可能在某个阶段遇到异常后需要重试。而多次重试之间可以设定一段休眠时间,防止因频繁重试导致系统出现更恶劣的情况。这时候需要suspend当前运行的Procedure,等待设定的休眠时间之后,再重新进入调度队列,继续运行这个Procedure。
下面仍然以上文讨论过的CreateTableProcedure为例,说明Procedure的Suspend过程。首先,需要理解一个简单的概念——DelayedQueue,也就是说每个Suspend的Procedure都会被放入这个DelayedQueue队列,等待超时时间消耗完之后,一个叫作TimeoutExecutorThread的线程会把Procedure取出,放到调度队列中,以便继续执行。

4,Procedure Yield

Procedure v2框架还提供了另一种处理重试的方式——把当前异常的Procedure直接从调度队列中移走,并将Procedure添加到调度队列队尾。等待前面所有的Procedure都执行完成之后,再执行上次有异常的Procedure,从而达到重试的目的。

HBase 2.x版本的大量任务调度流程都使用Procedure v2重写,典型如建表流程、删表流程、修改表结构流程、Region Assign和Unassign流程、故障恢复流程、复制链路增删改流程等。当然,仍然有一些管理流程没有采用Procedure v2重写,例如权限管理(HBASE-13687)和快照管理(HBASE-14413),这些功能将作为Procedure v2的第三期功能在未来的HBase3.0中发布,社区非常欢迎有兴趣的读者积极参与。
另外,值得一提的是,由于引入Procedure v2,原先设计上的缺陷得到全面解决,因此在HBase 1.x中引入的HBCK工具将大量简化。当然,HBase 2.x版本仍然提供了HBCK工具,目的是防止由于代码Bug导致某个Procedure长期卡在某个流程,使用时可以通过HBCK跳过某个指定Prcedure,从而使核心流程能顺利地运行下去。

二、In Memory Compaction

在HBase 2.0版本中,为了实现更高的写入吞吐和更低的延迟,社区团队对MemStore做了更细粒度的设计。这里,主要指的就是In Memory Compaction。
一个表有多个Column Family,而每个Column Family其实是一个LSM树索引结构,LSM树又细分为一个MemStore和多个HFile。随着数据的不断写入,当MemStore占用内存超过128MB(默认)时,开始将MemStore切换为不可写的Snapshot,并创建一个新MemStore供写入,然后将Snapshot异步地flush到磁盘上,最终生成一个HFile文件。可以看到,这个MemStore设计得较为简单,本质上是一个维护cell有序的ConcurrentSkipListMap。

1,Segment

Segment本质上是维护一个有序的cell列表。
根据cell列表是否可更改,Segment可以分为两种类型:
(1)MutableSegment:该类型的Segment支持添加cell、删除cell、扫描cell、读取某个cell等操作。因此一般使用一个ConcurrentSkipListMap来维护列表。
(2)ImmutableSegment:该类型的Segment只支持扫描cell和读取某个cell这种查找类操作,不支持添加、删除等写入操作。因此简单来说,只需要一个数组维护即可。
注意:无论是何种类型的Segment,都需要实时保证cell列表的有序性。

2,CompactingMemstore

在这里插入图片描述
在HBase 2.0中,设计了CompactingMemstore。CompactingMemstore将原来128MB的大MemStore划分成很多个小的Segment,其中有一个MutableSegment和多个ImmutableSegment。该Column Family的写入操作,都会先写入MutableSegment。一旦发现MutableSegment占用的内存空间超过2MB,则把当前MutableSegment切换成ImmutableSegment&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晓之以理的喵~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值