八、负载均衡实现

2020-01-13  本文已影响0人  loukey_j

1、Region迁移

1.1、HBase中,分片迁移就是Region迁移。和其他很多分布式系统不同,HBase中Region迁移时一个非常轻量级的操作,因为HBase的数据实际存储在HDFS上,不需要独立进行管理,因而Region在迁移过程中不需要迁移实际的数据,只要将读写服务迁移即可。

1.2、迁移流程分2个阶段unassign 和 assign

1.2.1、unassign阶段:表示Region从源RegionServer下线

1)Master生成事件M_ZK_REGION_CLOSSING并更新到ZK组件,同时将本地内存中该Region的状态修改为PENDING_CLOSE

2)Master通过RPC发送close命令给拥有该region的RegionServer,令其关闭Region

3)RS收到Master指令后,生成RS_ZK_REGION_CLOSING事件更新到ZK

4)Master监听到该节点变动后,更新状态为CLOSING

5)RS执行Region关闭操作,如果该Region正在执行flush或者Compaction,等待操作完成;否则强制将该Region下的MemStore进行flush,然后关闭Region服务

6)关闭完成生成事件RS_ZK_REGION_CLOSED,更新到ZK.Master监听到该节点变动后,更新状态为CLOSED

1.2.2、assign阶段:表示新的Region在RegionServer上线

1)Master生成事件M_ZK_REGION_OFFLINE并更新到ZK,同时将本地内存中的该Region的状态修改为PENDING_OPEN

2)Master通过RPC发送open命令给拥有该Region的RegionServer,令其打开Region

3)RS接收到Master命令后生成RS_ZK_REGION_OPENING事件更新到ZK

4)Master监听到该节点变动后,更新状态为OPENING

5)RS执行Region打开操作,初始化相应的服务

6)打开完成后生成事件RS_ZK_REGION_OPENED更新到ZK.Master监听到该节点变动后,更新状态为OPENED

1.3、Region In Transition

Region的状态会存在三个区域:meta表,Master内存,ZK的region-in-transition.并且作用不同,说明如下

1.3.1、meta表:

存储Region所在的RegionServer,并不存储迁移过程的中间状态,Region从rs1迁移到rs2,那么meta表就持久化Region到rs2的对应关系

1.3.2、Master内存:

Master存储整个集群中所有Region信息即:Region当前以什么状态在哪个RegionServer上,Master中Region状态变更总是滞后于真正Region的状态变更,因为Master收到的状态都是由ZK通知到的。我们在HBase Master WebUI看到的都是来自于Master内存信息

1.3.3、ZK中的内存:

ZK中存储的时临时性的状态转移信息,ZK作为Master和RegionServer之间反馈Region状态的通道,如果中间某环节发生异常,恢复之后可以根据ZK的状态继续进行迁移操作

1.3.4、只有这三个状态保持一致,对应的Region才处于正常的工作状态。在异常情况下,Region状态在三个地方的不能保持一致,这就会出现region-in-transition(RIT)状态。

1.3.5、在迁移过程中必然会出现短暂的RIT状态,这种场景并不需要人工干预操作。

2、Region合并

Region合并使用场景比较有限,最典型的一个应用场景是,在某些业务种本来接收写入的Region不再接收任何写入请求,而且Region上的数据因为TTL过期被删除

3、Region分裂

3.1、Region 分裂触发策略

3.1.1、0.94版本之前默认,一个Region中最大Store的大小超过设置的阈值就会触发分裂,弊端:阈值设置大对大表友好,对小表有可能不会触发分裂,可能只有一个Region.阈值设置小,对小表友好,对大表不友好,一个大表就会再整个集群产生大量小的Region,对集群管理,资源使用不是一件好事。

3.1.2、0.94版本~2.0版本默认分裂策略,和0.94版本之前的区别是阈值是动态调整的,调整后的阈值大小和Region所属RegionServer上的Region个数有关系。弥补了0.94版本之前的短板,能够自适应大表和小表,在大集群中很多大表来说很优秀,但是在大集群中有很多小标就会产生很多小的Region。

3.1.3、2.0版本的默认分裂策略,分列阈值大小和待分裂Region所属表在当前RegionServer上的Region个数有关系,这种分裂策略队医大集群中的大表、小表会比前两种更加友好,小表不会再产生大量的小region.

3.2、寻址分裂点

整个Region中最大Store中的最大文件中最中心的一个Block的首个rowkey。

3.3、Region核心分裂流程

3.3.1、将整个分裂过程包装成了一个事务,目的是保证分裂事务的原子性,分三个阶段

3.3.2、prepare阶段

内存中初始化两个子region,包含tableName,regionName,startkey,endkey等

3.3.3、exceute阶段

1)RegionServer将在ZK节点/region-in-transistion 更新该Region状态为SPLITING.

2)Master通过watch ZK节点的变化修改Region的状态

3)在HDFS Region父存储目录新建临时目录.split,用来保存split后的 daugther region信息。

4)关闭Region。父region关闭数据写入并触发flush,将region的数据全部持久化到磁盘,此后短时间内客户端落在父region的请求都会抛出异常。

5)在.split下新建两个文件夹,称为daughterA,daughterB;并在文件夹内生成reference文件,分别指向父region中对应文件夹

HDFS上文件变化如下

.../parent_region_name/cloumn_family/hfiles

../parent_region_name/.splits/

../parent_region_name/.splits/daughterA/

.../parent_region_name/.splits/daughterB/cloumn_family/reference_files

.../parent_region_name/.splits/daughterA/cloumn_family/reference_files

reference文件名由父region对应HFile文件和父region组成。可见通过文件就可以知道reference文件指向哪个父region的哪个Hfile

reference文件内容并不是用户数据,而是由两部分组成,一是:分裂点,二是:一个boolean类型的变量,true表示reference文件引用父文件的上半部分,false表示分裂点的下半部分

6)父region分裂为两个子Region之后,将daughterA,daughterB,拷贝到HBase根目录,形成两个新的Region

7)父Region通知修改hbase:meta表后下线,不在提供提供服务:修改meta表的split列为true,offline为true

8)开启daughterA,daughterB两个子region,通知修改meta表对外提供服务

3.3.4、rollback阶段

如果excute阶段出现异常,执行rollback操作,为了实现回滚,整个分裂过程分为很多子阶段,回滚程序根据当前进展到哪个子阶段清理对应的垃圾数据。

3.4、Region分裂原子性保证

Region分裂涉及都很多子步骤,为了实现原子性,HBase使用状态机的方式保存分裂过程中的每个子步骤的状态,一旦出现异常,就可以根据当前状态决定是否回滚,以及如何回滚。遗憾的是,目前实现中这些状态都只存储在内存中,一旦分裂过程中出现了RegionServer宕机,有可能出现分裂处于中间状态,也就是RIT。这种情况下需要使用HBCK工具进行分析解决方案。

3.5、Rgion分裂中没有涉及到数据的移动,所以分裂成本本身并不高,可以很快就完成。

4、HBase的负载均衡策略

HBase目前支持两种负载均衡的策略

4.1、SimpleLoadBalance策略

能够保证每个RegionServer的region个数基本相等。缺点:没有考虑RegionSever上的数据量和读写QPS等。

4.2、StochasticLoadBalance策略

这是默认策略,此策略考虑的因素更多,是由多种独立负载加权计算的复合值,这些独立负载指标包括

Region个数、Region负载、读请求数、写请求数、StoreFile大小、MenStore大小、数据本地率、移动代价

上一篇下一篇

猜你喜欢

热点阅读