HBase 架构

HBase 架构

HBase 是一个在 HDFS 上开发的面向列的分布式数据库。

HBase 存储架构

在 HBase 中,表被分割成多个更小的块然后分散的存储在不同的服务器上,这些小块叫做 Regions,存放 Regions 的地方叫做 RegionServer。Master 进程负责处理不同的 RegionServer 之间的 Region 的分发。

概览

img

HBase 主要处理两种文件:预写日志(WAL)和实际数据文件 HFile。一个基本的流程是客户端首先联系 ZooKeeper 集群查找行键。上述过程是通过 ZooKeeper 获取欧含有 -ROOT- 的 region 服务器来完成的。通过含有 -ROOT- 的 region 服务器可以查询到含有 .META. 表中对应的 region 服务器名,其中包含请求的行键信息。这两种内容都会被缓存下来,并且只查询一次。最终,通过查询 .META. 服务器来获取客户端查询的行键数据所在 region 的服务器名。

Region

HBase Table 中的所有行按照 Row Key 的字典序排列。HBase Table 根据 Row Key 的范围分片,每个分片叫做 Region。一个 Region 包含了在 start key 和 end key 之间的所有行。

img

HBase 支持自动分区:每个表初始只有一个 Region,随着数据不断增加,Region 会不断增大,当增大到一个阀值的时候,Region 就会分裂为两个新的 Region。当 Table 中的行不断增多,就会有越来越多的 Region

Region 是 HBase 中分布式存储和负载均衡的最小单元。这意味着不同的 Region 可以分布在不同的 Region Server 上。但一个 Region 是不会拆分到多个 Server 上的。

img

Region Server

Region 只不过是表被拆分,并分布在 Region Server。

Region Server 运行在 HDFS 的 DataNode 上。它具有以下组件:

  • **WAL(Write Ahead Log,预写日志)**:用于存储尚未进持久化存储的数据记录,以便在发生故障时进行恢复。如果写 WAL 失败了,那么修改数据的完整操作就是失败的。
    • 通常情况,每个 RegionServer 只有一个 WAL 实例。在 2.0 之前,WAL 的实现叫做 HLog
    • WAL 位于 /hbase/WALs/ 目录下
    • 如果每个 RegionServer 只有一个 WAL,由于 HDFS 必须是连续的,导致必须写 WAL 连续的,然后出现性能问题。MultiWAL 可以让 RegionServer 同时写多个 WAL 并行的,通过 HDFS 底层的多管道,最终提升总的吞吐量,但是不会提升单个 Region 的吞吐量。
  • BlockCache读缓存。它将频繁读取的数据存储在内存中,如果存储不足,它将按照 最近最少使用原则 清除多余的数据。
  • MemStore写缓存。它存储尚未写入磁盘的新数据,并会在数据写入磁盘之前对其进行排序。每个 Region 上的每个列族都有一个 MemStore。
  • HFile将行数据按照 Key/Values 的形式存储在文件系统上。HFile 是 HBase 在 HDFS 中存储数据的格式,它包含多层的索引,这样在 HBase 检索数据的时候就不用完全的加载整个文件。HFile 存储的根目录默认为为 /hbase。索引的大小(keys 的大小,数据量的大小)影响 block 的大小,在大数据集的情况下,block 的大小设置为每个 RegionServer 1GB 也是常见的。
    • 起初,HFile 中并没有任何 Block,数据还存在于 MemStore 中。
    • Flush 发生时,创建 HFile Writer,第一个空的 Data Block 出现,初始化后的 Data Block 中为 Header 部分预留了空间,Header 部分用来存放一个 Data Block 的元数据信息。
    • 而后,位于 MemStore 中的 KeyValues 被一个个 append 到位于内存中的第一个 Data Block 中:

img

Region Server 存取一个子表时,会创建一个 Region 对象,然后对表的每个列族创建一个 Store 实例,每个 Store 会有 0 个或多个 StoreFile 与之对应,每个 StoreFile 则对应一个 HFile,HFile 就是实际存储在 HDFS 上的文件。

HBase 系统架构

img

和 HDFS、YARN 一样,HBase 也遵循 master / slave 架构

  • HBase 有一个 master 节点。master 节点负责协调管理 region server 节点
    • master 负责将 region 分配给 region server 节点;
    • master 负责恢复 region server 节点的故障。
  • HBase 有多个 region server 节点。region server 节点负责零个或多个 region 的管理并响应客户端的读写请求。region server 节点还负责 region 的划分并通知 master 节点有了新的子 region
  • HBase 依赖 ZooKeeper 来实现故障恢复。

Master Server

Master Server 负责协调 Region Server。具体职责如下:

  • 为 Region Server 分配 Region ;
  • 负责 Region Server 的负载均衡 ;
  • 发现失效的 Region Server 并重新分配其上的 Region;
  • GFS 上的垃圾文件回收;
  • 处理 Schema 的更新请求。

img

Region Server

  • Region Server 负责维护 Master Server 分配给它的 Region,并处理发送到 Region 上的 IO 请求;
  • 当 Region 过大,Region Server 负责自动分区,并通知 Master Server 记录更新。

img

ZooKeeper

HBase 依赖 ZooKeeper 作为分布式协调服务来维护集群中的服务器状态。Zookeeper 维护哪些服务器是活动的和可用的,并提供服务器故障通知。集群至少应该有 3 个节点。

ZooKeeper 的作用:

  • 保证任何时候,集群中只有一个 Master;
  • 存储所有 Region 的寻址入口;
  • 实时监控 Region Server 的状态,将 Region Server 的上线和下线信息实时通知给 Master;
  • 存储 HBase 的 Schema,包括有哪些 Table,每个 Table 有哪些 Column Family 等信息。

img

以上,最重要的一点是 ZooKeeper 如何保证 HBase 集群中只有一个 Master Server 的呢?

  • 所有 Master Server 会竞争 Zookeeper 的 znode 锁(一个临时节点),只有一个 Master Server 能够创建成功,此时该 Master 就是主 Master。
  • 主 Master 会定期向 Zookeeper 发送心跳。从 Master 则通过 Watcher 机制对主 Master 所在节点进行监听。
  • 如果,主 Master 未能及时发送心跳,则其持有的 ZooKeeper 会话会过期,相应的 znode 锁(一个临时节点)会被自动删除。这会触发定义在该节点上的 Watcher 事件,所有从 Master 会得到通知,并再次开始竞争 znode 锁,直到完成主 Master 的选举。

HBase 内部保留名为 hbase:meta 的特殊目录表(catalog table)。它维护着当前集群上所有 region 的列表、状态和位置。hbase:meta 表中的项使用 region 作为键。region 名由所属的表名、region 的起始行、region的创建时间以及基于整体计算得出的 MD5 组成。

HBase 读写流程

写入数据的流程

  1. Client 向 Region Server 提交写请求;
  2. Region Server 找到目标 Region;
  3. Region 检查数据是否与 Schema 一致;
  4. 如果客户端没有指定版本,则获取当前系统时间作为数据版本;
  5. 将更新写入 WAL Log;
  6. 将更新写入 Memstore;
  7. 判断 Memstore 存储是否已满,如果存储已满则需要 flush 为 Store Hfile 文件。

更为详细写入流程可以参考:HBase - 数据写入流程解析

读取数据的流程

以下是客户端首次读写 HBase 上数据的流程:

  1. 客户端从 Zookeeper 获取 META 表所在的 Region Server;
  2. 客户端访问 META 表所在的 Region Server,从 META 表中查询到访问行键所在的 Region Server,之后客户端将缓存这些信息以及 META 表的位置;
  3. 客户端从行键所在的 Region Server 上获取数据。

如果再次读取,客户端将从缓存中获取行键所在的 Region Server。这样客户端就不需要再次查询 META 表,除非 Region 移动导致缓存失效,这样的话,则将会重新查询并更新缓存。

注:META 表是 HBase 中一张特殊的表,它保存了所有 Region 的位置信息,META 表自己的位置信息则存储在 ZooKeeper 上。

img

更为详细读取数据流程参考:

HBase 原理-数据读取流程解析

HBase 原理-迟到的‘数据读取流程部分细节

参考资料