浅析HBase架构

Posted by JustDoDT on July 5, 2019

HBase 组件概述

主从模式:HBase 体系结构遵循传统的 主从 模式,在HBase 中master 为 HMaster,slave 为 HRegionServers,主从之间通过 Zookeeper 共享状态信息。

HBase 组成:从物理层面,分为3个部分:

  • RegionServers
  • HMaster
  • Zookeeper

RegionServers 为客户端的读写提供数据,访问数据时,客户端直接与 RegionServers 通信。Region 分配、DDL(创建,删除)操作则由 HMaster 处理。Zookeeper 维护这一个集群的状态。

所有的 HBase 的Hfile的数据都存储在 HDFS 中,即 DataNode 负责存储RegionServers 正在管理的数据。实际的架构中,会在每个 DataNode 节点上部署一个对应的 RegionSevers,这使得 RegionSevers 所管理的数据距离实际的存储更接近,这也符合了 HDFS 目标之一:移动计算而非移动数据。

HBase

HRegionServers

RegionServers 主要负责服务和管理 Regions,它提供面向数据和 Region 维护的方法,其中包括:

  • 数据的读写、删除等
  • Region 的分离(Split)、压缩(compact)等

Region

Region 是 Table 可用性和分布的基本元素,由每个列族(ColumnFamily)的一个库(Store) 组成。其对象层级如下:

- Table
  - Region
    - Store(由每个 Region 中的列族组成的存储块)
      - MemStore(每个 Region 中存储在内存中的 Store)
      - StoreFile(每个 Region 中被持久化后的 Store)
        - Block (StoreFile 内被分块存储后的块)

分区存储: HBase 按照行键(RowKey)范围水平划分 Regions,一个 Region 包含了该 Region 的 startKey (开始键)到 endKey (结束键)之间的所有行。这些 Region 被分配给各个 RegionServers,每个 RegionServer 可以服务约 1000 个 Region。

HBase

HMaster

HMaster 是 Master Server 的实现,它负责监视集群中的所有 RegionServer 实例,并且提供所有元数据更改的接口。HMaster 主要功能包括:

  • 协调 RegionServer
    • 在启动时分配 Region、重新分配 Region 以恢复或负载均衡
    • 监控集群中的所有 RegionServers 节点(侦听来自 Zookeeper 的通知)
  • 管理功能
    • 提供创建、修改、删除、启动、禁用 table 的接口
    • 管理 namesapce 和 table 的元数据
    • 管理 Region 的移动、分配、取消分配
    • 权限控制

HBase

同时,HMaster 运行着几个后台进程,包括:

  • 负载平衡器(LoadBalancer): 定期地,如果没有任何 Region 被转换时,负载平衡器将运行并移动 Region 平衡集群负载;
  • Catalog Janitor: 定期检查并清理 .META 表。

Zookeeper

HBase 使用 Zookeeper 作为分布式协调服务来维护集群中的服务器状态。Zookeeper 维护哪些服务器处于活动状态并可用,并提供服务器故障通知。Zookeeper 使用共识算法来保证共同的共享状态。根据 Zookeeper 使用的 Paxos 算法特性,至少应该有三至五台(奇数)机器达成共识。

HBase

组件间如何协同工作

使用 Zookeeper 共享成员信息: HBase 使用 Zookeeper 来协调 HMasters 与 RegionServers 成员的共享状态信息。RegionServers 和活动状态的 HMaster 通过会话连接到 Zookeeper,并在 Zookeeper 上创建一个临时节点以表示其处于活动状态。Zookeeper 则通过接收各成员的心跳信息来维护会话的临时节点,如果RegionServers 或活动的 HMaster 未能向 Zookeeper 发送心跳,则代表会话过期,Zookeeper 将删除相应的临时节点。HMaster 通过监听 Zookeeper 上 RegionServer 创建的临时节点来发现可用的 RegionServer,并监控这些节点的服务器故障。

HBase

HMaster 选举: HMaster 通过争夺创建一个短暂的节点,Zookeeper 会选择第一个来确保只有一个 HMaster 处于活动状态。活动的 HMaster 将心跳发送到 Zookeeper,非活动状态的 HMaster 将监听活动的 HMaster 故障的通知,一旦发现活动的 HMaster 失败,则非活动的 HMaster 将变为活动状态。

RegionServers 的组件

RegionServer 作为管理 Region,并直接与客户端传输数据的节点,其运行在 HDFS 的 DataNode 节点之上,并具有以下组件:

  • WAL: 预写日志,用于存储尚未被永久保存的新数据,它以文件的形式存储在分布式文件系统(通常是 HDFS)上,其主要作用是用于故障后的恢复;
  • BlockCache: 读取缓存,它将频繁读取的数据存储在内存中,用以加快客户端的读取速度。最近最少使用的数据将在 BlockCache 满时被逐出,其默认的最大值为 Java 堆大小 * 0.4,默认的缓存方式为 LruBlockCache(一种完全在 Java 堆内的缓存,另外一种方式为 BucketCache);
  • MemStore: 写入缓存,它存储尚未写入磁盘的新数据,用以减少磁盘 IO 频率。它在写入磁盘之前将进行排序。每个 Region 的每个列族都有一个 MemStore。
  • HFiles: 用于将行数据作为已排序的 KeyValues 结构存储在磁盘上的最终文件,一个 Region 通常包含多个 HFile。

HBase

HFile (StoreFile)

HBase 的数据最终被存储在 HFile 中,HFile 是保存在 HDFS 中的物理文件(默认大小为 128M),它包含已经排序过的 KeyVelue 数据。

注:HFile 中的数据是有序的,但同一个 Region 下的所有 HFile 并不一定是连续有序的。

当 MemStore 累积足够的数据时(默认为128M),整个已排序的 KeyValues 将被写入 HDFS 中的新的 HFile 文件中(这是一个顺序写入,避免了移动磁盘驱动器磁头,所以它的速度会非常快)。

HBase

KeyValue

KeyValue 类是 HBase 中数据存储的核心。KeyValue 包装一个字节数组,并将偏移量和长度放入传递的数组中,指定将内容开始解释为 KeyVelue 的位置。

字节数组中的 KeyValue 数据结构表现为:

{
    keylength,
    valuelength,
    key: {
        rowLength,
        row (i.e., the rowkey),
        columnfamilylength,
        columnfamily,
        columnqualifier,
        timestamp,
        keytype (e.g., Put, Delete, DeleteColumn, DeleteFamily)
    }
    value

注:keytype 用来标识数据操作类型,当删除操作发生时,HBase 新建一条相同的数据,并使 keytype=delete,便代表了此数据被删除。

Block

StoreFile(HFile) 由 block 组成,block 的大小基于每个 ColumnFamily 进行配置,可在创建表时指定,默认大小为 64 KB。数据压缩也是发生在 block 级别。

HFile 结构

HFile 包含一个多层索引,它允许 HBase 在不必读取整个文件的情况下查找数据。多级索引就像一颗 B+ 树,它具有如下特点:

  • KeyValue 对按升序存储
  • 索引指向包含 KeyValue 数据的“block”(默认大小为 64KB)
  • 每个 block 都有自己的叶子索引(Leaf ndex)
  • 每个 block 的最后一个 key 放在中间索引(Intermediate index)中
  • 根索引指向中间索引

同时,文件的结尾包含一个 trailer 信息,它指向所有的块。并且该 tariler 还具有 Bloom 过滤器和时间范围等信息。Bloom 过滤器有助于跳过不包含某个行键的文件。如果文件不再读取的时间范围内,则时间范围信息对于跳过该文件非常有用。

注:一个 keyValue 不会在 block 之间被拆分,即如果一个 KeyValue 大小为 8M,即使 block 大小设置是 64KB,这个 KeyValue 也将作为一个连贯的 block 被存储。

HBase

HFile 索引

HFile 的索引是在 HFile 打开并保存在内存中时被加载的,它被保存在 BlockCache(即读取缓存)中,这就允许通过单个磁盘寻道来执行查找功能。

HBase

Region 概述

在 HBase 中,Region 是有效性和分布的基本单位,这通常也是我们在维护时能直接操作的最小单位。比如当一个集群的存储在各个节点不均衡时,HMaster 便是通过移动 Region 来达到集群的平衡。或者某一个 Region 的请求过高时,通过分裂 Region 来分散请求。或者我们可以指定 Region 的 startKey 和 endKey 来设计它的数据存放范围等等。

所以,HBase 在读写数据时,都需要先找到对应的 Region,然后再通过具体的 Region 进行实际的数据读写。

目录表(Catalog Tables)

客户端在访问 Region 中的数据之前,需要先通过 HMaster 确定 Region 的位置,而 HMaster 则将所有 Region 的元信息都保存在 hbase:meta 中。

hbase:meta

Meta 表是一个特殊的 HBase 表,它保存了集群中所有 Region 的列表,它的地址被存储在 Zookeeper 中。其表结构如下:

- RowKey:
    - Region Key 格式([table],[region start key],[region id])
- Values:
    - info:regionInfo (序列化的.META.的HRegionInfo实例)
    - info:server(保存.META.的RegionServer的server:port)
    - info:serverStartCode(保存.META.的RegionServer进程的启动时间)

根据 Meta 表中的数据,可以确定客户端所访问的 RowKey 所处的实际位置。

HBase

读取与缓存元数据(首次读取或写入)

客户端第一次读取或写入 HBase 时将发生以下步骤:

  • 客户端从 Zookeeper 获取存储 META 表的 Region 服务器地址;
  • 客户端查询 META 表所在服务器来获取与想要访问的行键相对应的 RegionServer 地址,然后客户端将这些信息与 META 表位置一起缓存;
  • 客户端从对应的 RegionServer 获取指定行;

对于之后的读取,客户端使用缓存的信息来检索 META 的位置和已经读取过的行键位置信息。随着时间的推移,它将不需要查询 META 表,直到由于某个 Region 已经移动或丢失,客户端才会重新查询并更新缓存。

HBase

HBase 写入原理

在初次读取写入时,客户端已经缓存了 META 表的信息,同时因为在 HBase 中数据是按行键有序排列的,所以客户端能过通过将要写入数据的行键和缓存信息直接找到对应的 RegionServer 和 Region 位置。那么当客户端发出 Put 请求直到数据真正写入磁盘,它将主要经过以下步骤:

  • 将数据写入预写日志 WAL
  • 写入并排序 MemStore 缓存数据
  • 刷新缓存中的数据,并写入到 HFile磁盘

1. 将数据写入预写日志 WAL

当客户端发出 Put 请求时,HBase 首先会将数据写入预写日志:

  • 编辑 WAL 文件,将数据附加到 WAL 文件的末尾(满足 HDFS 只允许追加的特性);
  • 如果服务器崩溃,那么将通过 WAL 文件恢复尚未保存的数据;

HBase

2. 写入并排序 MemStore 缓存数据

一旦数据写入 WAL 成功后,数据将被放入 MemStore 中,然后将 Put 请求确认返回给客户端。客户端接收到确认信息后,对于客户端来说,此次操作便结束了。

HBase

数据放入 MemStore 中后,HBase 不会立即刷新数据到磁盘,而是先更新存储数据使其作为有序的 KeyValues 结构,与存储在 HFile 中的结构相同,并等待 MemStore 累积到足够的数据时才会刷新数据以写入磁盘。

HBase

3. 刷新缓存中的数据,并写入到 HFile磁盘

当 MemStore 累积到足够的数据时,整个有序的数据集将被写入 HDFS 中的一个新的 HFile 文件。至此,客户端从发出 Put 请求到数据持久化的过程才算是真正的完成。

可能影响性能的因素

  • 因为每一个列族都有一个 MemStore,而当发生刷新时,属于同一个 Region 下的所有 MemStore 都将刷新,这可能导致性能下降,并影响最终的 HFile 文件大小(HDFS 不适合存储小文件),所以列族的数量应该被限制以提高整体效率。

HBase 读取原理

根据 HBase 的 RegionServers 的结构可知:在 HBase 中,与一行数据相对应的 KeyValue 单元格可能位于多个位置,比如:行单元格(row cells)已经保存在 HFiles 中,最近更新的单元格位于 MemStore 中,最近读取的单元格位于 BlockCache 中。所以当客户端读取一行数据时,HBase 需要将这些数据合并以得到最新的值。

读取合并

HBase 将通过以下步骤来合并 BlockCache、MemStore 和 HFile 中的数据:

  • 首先,扫描程序查找 BlockCache 中的行单元格(读取缓存)。最近读取的 keyValue 被缓存在这里,并且当需要使用内存时,清除掉最近使用最少的数据;
  • 然后,扫描器在 MemStore 中查找包含最近写入内存中的缓存数据;
  • 如果扫描器在 MemStore 和 BlockCache 中没有找到所有的行单元格,HBase 将使用 BlockCache 索引和 Bloom 过滤器将 HFile 加载到内存中,它可能包含目标行单元格。

注:Bloom 过滤器确定的结果并不一定总是准确的,但是否定的结果却一定保证准确。

HBase

可能影响性能的因素

  • 刷新数据时,一个 MemStore 可能会产生多个相同的 HFile 文件(为什么会产生多个相同的文件?),这意味着读取时可能需要检查多个文件,这可能会影响性能。这种行为被称为读取放大;
  • 客户端使用扫描全表数据操作时,可能会检查更多的文件,所以不建议使用扫描全表操作;

HBase 删除原理

HBase 的删除操作并不会立即将数据从磁盘上删除,这主要是因为 HBase 的数据通常被保存在 HDFS 之中,而 HDFS 只允许新增或者追加数据文件,所以删除操作主要是对要被删除的数据打上标记。

HFile 中保存了已经排序过的 KeyValue 数据,KeyValue 类的数据结构如下:

{
    keylength,
    valuelength,
    key: {
        rowLength,
        row (i.e., the rowkey),
        columnfamilylength,
        columnfamily,
        columnqualifier,
        timestamp,
        keytype (e.g., Put, Delete, DeleteColumn, DeleteFamily)
    }
    value

注意:当执行删除操作时,HBase 新插入一条相同的 KeyValue 数据,但是使 keytype=Delete,这便意味着数据被删除了,直到发生 Major_compaction 操作时,数据才会被真正的从磁盘上删除。

Compacation

HBase 在读写的过程中,难免会产生无效的数据以及过小的文件,比如:MemStore 在未达到指定大小便刷新数据以写入到磁盘;或者当已经写入 HFile 的数据被删除后,原数据被标记了墓碑,却仍然存在于 HFile 之中。在这些情况之下,我们需要清除无效的数据或者合并过小的文件来提高读的性能。这种合并的过程也被称为 compacation。

HBase 中使用的 compacation 方式主要分为以下两种:

  • Minor_compaction
  • Major_compaction

Minor_Compaction

HBase 会自动选择一些较小的 HFile,并将它们重写成更少的但更大的 HFiles 文件,这个过程被称为 minor_compaction。minor_compaction 通过将少量的相邻的 HFile 合并为单个 HFile 来达到压缩操作,但是它不会删除被标记为删除或过期的数据。

HBase

Major_Compaction

Major_Compaction 将 Region 中的所有 HFile 合并并重写成一系列由列族(Column Family)组成的 HFile 文件,并在此过程删除已被删除或已过期的数据。这会提高读取性能,但是由于 Major_compaction 会重写所有文件,所以在此过程中可能会发生大量的磁盘 I/O 和网络流量,这种现象被称为写入放大(write amplification)。

HBase

Region Split

最初,每一个 table 都会有一个 Region。随着数据的不断写入,当这个 Region 变得太大时,它就会被分裂成两个子 Regions。两个子 Regions 各种拥有原 Region 的一半,它们会在相同的 RegionServer 上并行打开,然后将分区信息报告给 HMaster。处于负载均衡的原因,HMaster 可能会将新的 Region 移动到其它服务器。

HBase

负载均衡

Split 最初发生在同一个 RegionServer 上,但是出于负载均衡的原因,HMaster 可能会将新的 Region 移动到其它服务器(移动元数据,而不是 HFile 文件)。这会导致新的 RegionServer 提供来自远程 HDFS 节点的数据,直到 Major_compaction 时将数据文件移动到区域服务器的本地节点。

HBase

故障恢复

WAL 文件和 HFile 被保存在磁盘上并被复制,但是 MemStore 还没有被保存在磁盘上,所以当 RegionServer 发生问题后,HBase 是如何恢复 MemStore 之中的数据呢?

HBase

当 RegionServer 失败时,崩溃的 Region 将不可用,直到检查并恢复之后方可继续使用。Zookeeper 会在失去 RegionServer 心跳时确定节点故障,HMaster 将会被通知 RegionServer 已经失败。

注:当 RegionServer 失败时,正在查询该节点上的数据的操作会被重试,并且不会立即丢失。

当 HMaster 检测到 RegionServer 已经崩溃时,HMaster 会将已崩溃的 RegionServer 上的 Regions 重新分配给活动的 RegionServer。为了恢复已崩溃的 RegionServer 上未刷新到磁盘的 MemStore 中的内容,HMaster 将属于崩溃的 RegionServer 的 WAL 文件拆分成单独的文件,并将这些文件存储在新的 RegionServer 的 DataNode 上。然后新的 RegionServer 根据拆分后的 WAL 文件重播 WAL,以重建丢失的 MemStore 区域。

HBase

WAL 重播

WAL 文件包含编辑列表,一个编辑表示单个操作的 put 或者 delete。编辑按照时间顺序写入,并将附加到存储在磁盘上的 WAL 文件的末尾。

如果数据仍在 MemStore 中并且未保存到 HFile 中时,将发生 WAL 重播。WAL 重播是通过读取 WAL 文件,将其包含的编辑操作添加到当前的 MemStore 并进行排序来完成的。

Region

Region 是表格可用性和分布的基本元素,由列族(Column Family)构成的 Store 组成。对象的层次结构如下:

- Table
    - Region
        - Store         (由每个 Region 中的列族组成的存储块)
            - MemStore  (每个 Region 中存储在内存中的 Store)
            - StoreFile (每个 Region 中被持久化后的 Store)
                - Block (StoreFile 内被分块存储后的块)

其中 StoreFile 在 HDFS 中的存储路径为:

/hbase
    /data
        /<Namespace>                    (Namespaces in the cluster)
            /<Table>                    (Tables in the cluster)
                /<Region>               (Regions for the table)
                    /<ColumnFamily>     (ColumnFamilies for the Region for the table)
                        /<StoreFile>    (StoreFiles for the ColumnFamily for the Regions for the table)

1. Region 数量

通常而言,HBase 被设计成每台服务器运行一个数量较小的(20 - 200)但大小相对较大(5 - 20 GB)的 Region。那么为什么应该保持 Region 数量较低?

以下是保持较低 Region 数量的一些原因:

  1. 每个 MemStore 需要 2MB 的 MSLAB(MemStore-local 分配的 buffer)- 相当于每个 Region 的每个列族(ClounmFamily)需要 2MB 的 MSLAB。那么 1000 个有 2 个列族的 Region 将使用 2MB * 1000 * 2 = 4000MB ~= 3.9GB 的堆内存,甚至都还没有开始存储数据。注:MSLAB 的大小是可配置的,默认为 2MB.

  2. 如果以相同的速率填充所有的 Region,则全局内存使用情况会在因为 Region 太多而产生 compaction 操作时,强制进行微小的刷新。举个例子:平均填充1000个Region(有一个列族),假如有5GB的全局 MemStore 使用的下限(RegionServer有一个大的堆),一旦它达到5GB,它将强制刷新最大的 Region,那时每个 Region 大约都是 5MB 的数据,所以它会刷新这个 Region。稍后再插入 5MB,它将刷新另一个 Region,依次类推。目前这个是 Region 数量的主要限制因素。更多请参阅。。。

    举个实例来说:目前的一个集群单台 RegionServer 分配的内存大小为 32GB,其中所有的 MemStore 的最大大小比例设置为 0.4,即最大大小为 32GB * 0.4 = 12.8GB

  3. Master 很讨厌太多的 Region,因为这可能需要大量的时间分配并批量移动。

  4. 在比较旧版本的 HBase(HFile v2, 0.90 之前的版本)中,几个 RegionServer 上的大量的 Region 会导致存储文件索引上升,增加堆使用量,并可能在 RS 导致内存压力或 OOM。

  5. 另外一个问题是 Region 数量对 MapReduce 作业的影响。每个 HBase Region 都有一个映射器是很典型的,因此,每个 RS 仅托管 5 个 Region 可能不足以获得足够数量的 MapReduce 作业任务,但是 1000 个 Region 又将生成太多的任务。

请参考Determining region count and size配置 Region 数量。

2. Region-RegionServer 的分配

当 HBase 启动 RegionServer 分配时,简要过程如下:

  1. Master 在启动时调用 AssignmentManager;
  2. AssignmentManager 查看 hbase:meta 中的现有 Region 分配;
  3. 如果 Region 分配仍然有效(即,如果 RegionServer 仍处于联机状态),则保留分配;
  4. 如果分配无效,则调用 LoadBalancerFactory 来分配 Region。负载均衡器将 Region 分配给 RegionServer;
  5. hbase:meta 使用 RegionServer 分配(如果需要)和 RegionServer 的开始码(RegionServer进程的开始时间)在 RegionServer 打开 Region 时进行更新。

3. 故障转移

当 RegionServer 失败时:

  1. 由于 RegionServer 关闭,它上面的 Region 会立即变得不可用;
  2. Master 将检测到 RegionServer 失败;
  3. Region 分配将被视作无效,并将像启动顺序一个被重新分配;
  4. 重新尝试进行中的查询,不会丢失;
  5. 在以下时间段内,操作将切换到新的 RegionServer:
    ZooKeeper session timeout + split time + assignment/replay time
    

4. 负载平衡

Region 可以被负载平衡器(LoadBalancer)定期的移动。

5. 状态转换

HBase 维持每个 Region 的状态,并将它们的状态保存在 hbase:meat 表中,hbase:meta 的 Region 状态则保存在 Zookeeper 中。在 Master Web UI 中可以查看转换中的 Region 状态。以下是可能的 Region 状态列表:

  • OFFLINE: 该 Region 处于离线状态,无法打开
  • OPENING: 该 Region 正在打开
  • OPEN: 该 Region 已经打开,并且 RegionServer 已经通知 Master
  • FAILED_OPEN: RegionServer 打开该 Region 失败
  • CLOSING: 该 Region 正在关闭
  • CLOSED: RegionServer 关闭了该 Region,并通知了 Master
  • FAILED_CLOSE: RegionSever 关闭该 Region 失败
  • SPLITTING: RegionServer 通知 Master Region 正在分裂(splitting)
  • SPLIT: RegionServer 通知 Master Region 已经完成分裂
  • SPLITTING_NEW: 该 Region 正在进行通过分裂创建新的 Region
  • MERGING: RegionServer 通知 master 该 region 正在与另外一个 region 合并
  • MERGED: RegionServer 通知 master 该 region 已经合并完成
  • MERGING_NEW: 该 Region 由两个 Region 合并完成

状态转换图如下:

HBase

图示说明:

  • 棕色:离线状态,一种特殊状态,可以是暂时的(打开之前关闭后)、最终的(被 disabled 表的 regions)或者初始的(新建表的 region)
  • 淡绿色:在线状态,region 可以为请求提供服务
  • 淡蓝色:过渡状态,瞬时的
  • 红色:失败状态,需要管理员关注,通常无法写入数据可能就是它照成的
  • 黄金:regions split/merged 后的最终状态
  • 灰色:通过 split/merged 并创建的新的 region 的初始状态

过渡状态描述

  1. Master将Region从OFFLINE转换成OPENING状态,并尝试将该区域分配给RegionServer。RegionServer可能收到也可能未收到开放Region的请求。Master会重试将打开Region请求发送RegionServer,直到RPC通过或Master用完重试。在RegionServer收到打开Region请求后,RegionServer开始打开Region;

  2. 如果Master重试超时,则即使RegionServer正在打开Region,Master也会通过将Region转换为CLOSING状态并尝试关闭它来阻止RegionServer继续打开该Region;

  3. RegionServer打开该Region后,它将继续尝试通知Master,直到Master将该Region转换为OPEN状态并通知RegionServer,该Region才算打开;

  4. 如果RegionServer无法打开Region,它会通知Master。然后Master将该Region转换为CLOSED状态,并尝试在其它的RegionServer上打开该Region;

  5. 如果Master无法打开某个Region,则会将Region转换为FAILED_OPEN状态,并且在管理员使用HBase shell操作之前或服务器死亡之前不会采取进一步的操作;

  6. Master将Region从OPEN转换为CLOSING状态。持有Region的RegionServer可能已经或可能未收到关闭Region请求。Maater将重试向服务器发送关闭请求,直到RPC通过或Master用尽重试;

  7. 如果RegionServer不在线或引发NotServingRegionException,则Master将该Region转换为OFFLINE状态,并将其重新分配给其它的RegionServer;

  8. 如果RegionServer处于联机状态,但在Master用完重试之后无法访问,则Master会将该Region移至FAILED_CLOSE状态,并且不会采取进一步的操作,直到操作员从HBase shell进行干预或服务器死亡;

  9. 如果RegionServer获得关闭Region请求,它会关闭该Region并通知Master。Master将该Reguib移至CLOSED状态并重新分配给其它的RegionServer;

  10. 在分配Region之前,如果Region处于CLOSED状态,Master会自动将Region转换为OFFLINE状态;

  11. 当一个RegionServer即将分裂(split)一个Region时,它通知Master,Master将Region从OPEN转换为SPLITTING状态,并将要创建的两个新Region添加到RegionServer。这两个Region最初处于SPLITTING_NEW状态。

  12. 在通知Master后,RegionServer开始分裂Region。一旦经过了不返回的地方,RegionServer会再次通知Master,以便Master可以更新hbase:meta表。不管怎样,在服务器通知分裂完成之前,Master不会更新Region的状态。如果分裂成功,则分裂的Region从SPLITTING转换为SPLIT状态,并且两个新的Region从SPLITTING_NEW转换为OPEN状态。

  13. 如果分裂失败,则分裂Region将从SPLITTING回到OPEN状态,并且创建的两个新的Region将从SPLITTING_NEW转换为OFFLINE状态;

  14. 当一个RegionServer即将合并(merge)两个Region时,它首先通知Master,Master将两个待合并的Region从OPEN转换为MERGING状态,并将拥有两个合并的Region内容的新的Region添加到并添加到RegionServer。新的Region最初处于MERGING_NEW状态。

  15. 通知Master后,RegionServer开始合并这两个Region。一旦经过不返回的地方,RegionServer再次通知Master,以便Master可以更新META表。但是,Master不会更新Region状态,直到RegionServer通知合并已完成。如果合并成功,则两个合并的 Region将从MERGING状态变为MERGED状态,并且新的 Region 将从MERGING_NEW转换为OPEN状态;

  16. 如果合并失败,则将两个合并的Region从MERGING更改回OPEN状态,并且创建的用于容纳合并Region内容的新的Region将从MERGING_NEW转换为OFFLINE状态。

  17. 对于处于FAILED_OPENFAILED_CLOSE状态的Region,Master在通过HBase Shell重新分配它们时尝试再次关闭它们。

可能产生的影响

了解Region的状态变化过程十分重要,因为Region的状态在发生更改时,如果发生异常,很可能需要管理员人工介入。而在人工介入之前,很有可能会影响到部分表的正常使用,示例可参见:HBase 部分表无法写入数据的异常处理

参考资料