本文系转载,如有侵权,请联系我:likui0913@gmail.com
一、HBase 组件概览
Master-Slave 模式: HBase 体系结构遵循传统的 master-slave 模式,由一位掌握决策的主设备和一个或多个真正处理任务的从设备组成。在 HBase 中,主设备称为 HMaster,从设备被称为 HRegionServers,主从设备之间则通过 Zookeeper 共享状态信息。
HBase 组成: 从物理层面,HBase 由 3 个部分:
- Region Servers
- HBase Master
- Zookeeper
它们在程序中的实现分别为:
- HRegionServers 节点
- HMaster 节点
- Zooeeper 节点
Region Servers 为客户端的读写提供数据,访问数据时,客户端直接与 Region Servers 通信。Region 分配、DDL(创建、删除表)操作则由 HBase Master 处理。Zookeeper 作为 HDFS 的一部分,维护者一个活动的集群的状态。
所有的 HBase 数据都存储在 HDFS 中,即 DataNode 负责存储 RegionServers 正在管理的数据。实际的架构中,会在每个 DataNode 节点上部署一个对应的 RegionSevers,这使得 RegionSevers 所管理的数据距离实际的存储更接近,这也符合了 HDFS 目标之一:移动计算而非移动数据。
HRegionServers
RegionServers 主要负责服务和管理 Regions,它提供面向数据和 Region 维护的方法,其中包括:
- 数据的读写、删除等
- Region 的分离(Split)、压缩(compact)等
Region
Region 是 Table 可用性和分布的基本元素,由每个列族(ColumnFamily)的一个库(Store) 组成。其对象层级如下:
1
2
3
4
5
6
7
8 1- Table
2 - Region
3 - Store(由每个 Region 中的列族组成的存储块)
4 - MemStore(每个 Region 中存储在内存中的 Store)
5 - StoreFile(每个 Region 中被持久化后的 Store)
6 - Block (StoreFile 内被分块存储后的块)
7
8
分区存储: HBase 按照行键(RowKey)范围水平划分 Regions,一个 Region 包含了该 Region 的 startKey (开始键)到 endKey (结束键)之间的所有行。这些 Region 被分配给各个 RegionServers,每个 RegionServer 可以服务约 1000 个 Region。
HMaster
HMaster 是 Master Server 的实现,它负责监视集群中的所有 RegionServer 实例,并且提供所有元数据更改的接口。HMaster 主要功能包括:
-
协调 RegionServer
-
在启动时分配 Region、重新分配 Region 以恢复或负载均衡
- 监控集群中的所有 RegionServers 节点(侦听来自 Zookeeper 的通知)
-
管理功能
-
提供创建、修改、删除、启动、禁用 table 的接口
- 管理 namesapce 和 table 的元数据
- 管理 Region 的移动、分配、取消分配
- 权限控制
同时,HMaster 运行着几个后台进程,包括:
- 负载平衡器(LoadBalancer): 定期地,如果没有任何 Region 被转换时,负载平衡器将运行并移动 Region 平衡集群负载;
- Catalog Janitor: 定期检查并清理 .META 表。
Zookeeper
HBase 使用 Zookeeper 作为分布式协调服务来维护集群中的服务器状态。Zookeeper 维护哪些服务器处于活动状态并可用,并提供服务器故障通知。Zookeeper 使用共识来保证共同的共享状态。根据 Zookeeper 使用的 Paxos 算法特性,至少应该有三至五台机器达成共识。
二、组件间如何协同工作
使用 Zookeeper 共享成员信息: HBase 使用 Zookeeper 来协调 HMasters 与 RegionServers 成员的共享状态信息。RegionServers 和活动状态的 HMaster 通过会话连接到 Zookeeper,并在 Zookeeper 上创建一个临时节点以表示其处于活动状态。Zookeeper 则通过接收各成员的心跳信息来维护会话的临时节点,如果RegionServers 或活动的 HMaster 未能向 Zookeeper 发送心跳,则代表会话过期,Zookeeper 将删除相应的临时节点。HMaster 通过监听 Zookeeper 上 RegionServer 创建的临时节点来发现可用的 RegionServer,并监控这些节点的服务器故障。
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。
HFile (StoreFile)
HBase 的数据最终被存储在 HFile 中,HFile 是保存在 HDFS 中的物理文件(默认大小为 128M),它包含已经排序过的 KeyVelue 数据。
注:HFile 中的数据是有序的,但同一个 Region 下的所有 HFile 并不一定是连续有序的。
当 MemStore 累积足够的数据时(默认为128M),整个已排序的 KeyValues 集将被写入 HDFS 中的新的 HFile 文件中(这是一个顺序写入,避免了移动磁盘驱动器磁头,所以它的速度会非常快)。
KeyVelue
KeyVelue 类是 HBase 中数据存储的核心。KeyVelue 包装一个字节数组,并将偏移量和长度放入传递的数组中,指定将内容开始解释为 KeyVelue 的位置。
字节数组中的 KeyVelue 数据结构表现为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 1{
2 keylength,
3 valuelength,
4 key: {
5 rowLength,
6 row (i.e., the rowkey),
7 columnfamilylength,
8 columnfamily,
9 columnqualifier,
10 timestamp,
11 keytype (e.g., Put, Delete, DeleteColumn, DeleteFamily)
12 }
13 value
14}
15
16
注: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 被存储。
HFile 索引
HFile 的索引是在 HFile 打开并保存在内存中时被加载的,它被保存在 BlockCache(即读取缓存)中,这就允许通过单个磁盘寻道来执行查找功能。
参考链接
- An In-Depth Look at the HBase Architecture
- Apache HBase ™ Reference Guide