主要内容:

  • HBase 基础总结

1、系统架构

HBase 采用主从架构搭建集群,主要由以下节点组成:

  • HMaster:负责 Region的分配,DDL(创建,删除 table)等操作。
  • HRegionServer:负责处理数据的读写请求,客户端请求数据时直接和 RegionServer 交互。
  • Zookeeper:负责维护集群状态。
  • HDFS:DataNode负责存储 RegionServer 所管理的 Region。所有的 HBase 数据都存储在 HDFS 文件中。Region Server 和 HDFS DataNode 往往是分布在一起的,这样 Region Server 就能够实现数据本地化(data locality,即将数据放在离需要者尽可能近的地方)。

2、Region

  • HBase 表根据RowKey 的范围被水平拆分成多个 Region。每个 Region 都包含了开始键 StartKey 和结束键 EndKey 之间的所有行,且是按 RowKey 排好序的。
  • 一个 Region 的大小可根据需要进行配置。
  • Region 被分配给集群中的某些节点来管理,即 Region Server,由它们来负责处理数据的读写请求。每个 Region Server 大约可以管理 1000 个 Region。

3、HMaster


  • 所有 Region Server 的管理者。类似于 Hadoop 集群中 DataNode 的角色。
  • 负责 Region 的分配,DDL(创建,删除表)等操作。
  • 维护整个集群的负载均衡。
  • 处理元数据的变更。
  • 监控集群中所有 Region Server 实例(从 Zookeeper 获取通知信息)。
  • 处理 RegionServer 故障转移。发现失效的 Region,并将失效的 Region 分配到正常的 RegionServer 上。

4、ZooKeeper


  • HBase 使用 Zookeeper 做分布式管理服务,来维护集群中所有服务的状态。Zookeeper 在 HBase 分布式环境中充当 Coordinator(协调器)。它通过 Session(会话通信)来帮助维护集群内的服务器状态。
  • 每个 Region Server 和 HMaster Server 都会定期向 Zookeeper 发送连续的心跳,并检查哪个服务器处于活动状态且可用。它还提供服务器故障通知,以便可以执行恢复措施。
  • 图中有一个非活动服务器,它充当活动服务器的备份。如果活动服务器发生故障,它会来救援。
  • Zookeeper 还维护了 .META 表,可以帮助客户端迅速定位到需要访问的 Region 所谓的 RegionServer。

5、Meta Table

Meta Table 是一个特殊的 Hbase 表,用于保存集群中 Regions 的位置信息。Meta Table 是一张系统表,其存储路径在 Zookeeper 的 HBase 节点下面。

HBase Meta 表结构:

  • Key:table, region start key, region id
  • Value:region server

6、Region Server


Region Server 运行在 HDFS DataNode 上,由以下组件组成:

  • WAL:Write Ahead Log 是分布式文件系统上的一个文件,用于存储新的还未被持久化存储的数据,它被用来做故障恢复。
  • BlockCache:这是读缓存,在内存中存储了最常访问的数据,是 LRU(Least Recently Used)缓存。
  • MemStore:这是写缓存,在内存中存储了新的还未被持久化到硬盘的数据。当被写入硬盘时,数据会首先被排序。注意每个 Region 的每个 Column Family 都会有一个 MemStore。
  • HFile :在硬盘上(HDFS)以有序 KeyValue 的形式存储 HBase 数据。

7、HBase Write

HBase 写数据的步骤:

  • Client 首先从 ZK 中查询到 Meta 表的 Region 位置,去对应的 Region Server 上找读取 Meta 表的数据,Meta 表存储了用户表的 Region 信息。
  • 根据 Namespace、Table Name、RowKey 信息找到写入数据所在的 Region 信息,找到对应的 Region Server,然后发送请求。
  • 先将数据写入 HLog(Write Ahead Log),然后写入 Memstore,即写缓存。
  • 然后服务端就可以向客户端返回 ack 表示写数据完成。

注意数据写入时 WAL 和 MemStore 更新的顺序,不能调换,必须先 WAL 再 MemStore。如果反过来,先更新完 MemStore,此时 Region Server 发生 crash,内存中的更新就丢失了,而此时数据还未被持久化到 WAL,就无法恢复了。理论上 WAL 就是 MemStore 中数据的一个镜像,应该保持一致,除非发生系统 Crash。另外注意更新 WAL 是在文件尾部追加的方式,这种磁盘操作性能很高,不会太影响请求的整体响应时间。

![hbase写数据流程](D:\Document\KKB\13-hbase\第二节:HBase核心原理\HBase day02\assets\hbase写数据流程.png)

8、Hbase MemStore


  • MemStore 总是按字典顺序将存储在其中的数据更新为排序的 KeyValue。 每个列族都有一个 MemStore,因此每个列族的更新以排序的方式存储。
  • MemStore 中累积了足够多的的数据后,整个有序数据集就会被写入一个新的 HFile 文件到 HDFS 上。HBase 为每个 Column Family 都创建一个 HFile,里面存储了具体的 Cell,也即 KeyValue 数据。随着时间推移,HFile 会不断产生,因为 KeyValue 会不断地从 MemStore 中被刷写到硬盘上。
  • 注意这也是为什么 HBase 要限制 Column Family 数量的一个原因。每个 Column Family 都有一个 MemStore;如果一个 MemStore 满了,所有的 MemStore 都会被刷写到硬盘。同时它也会记录最后写入的数据的最大序列号sequence number),这样系统就能知道目前为止哪些数据已经被持久化了。最大序列号是一个 meta 信息,被存储在每个 HFile 中,来表示持久化进行到哪条数据了,应该从哪里继续。当 region 启动时,这些序列号会被读取,取其中最大的一个,作为基础序列号,后面的新的数据更新就会在该值的基础上递增产生新的序列号。
  • 这里有个序列号的概念,每次 HBase 数据更新都会绑定一个新的自增序列号。而每个 HFile 则会存储它所保存的数据的最大序列号,这个元信息非常重要,它相当于一个 commit point,告诉我们在这个序列号之前的数据已经被持久化到硬盘了。它不仅在 region 启动时会被用到,在故障恢复时,也能告诉我们应该从 WAL 的什么位置开始回放数据的历史更新记录。

9、HBase HFile


  • 数据存储在 HFile 中,以 Key/Value 形式。
  • 当 MemStore 累积了足够多的数据后,整个有序数据集就会被写入一个新的 HFile 文件到 HDFS 上。整个过程是一个顺序写的操作,速度非常快,因为它不需要移动磁盘头。(注意 HDFS 不支持随机修改文件操作,但支持 append 操作。)


  • HFile 使用多层索引来查询数据而不必读取整个文件,这种多层索引类似于一个 B+ tree。索引文件在 HFile 被打开时会被载入内存,这样数据查询只要一次硬盘查询。

10、HBase Read 合并


每行的 KeyValue cells 可能位于不同的地方:

  • 可能被写入了 HFile
  • 可能是最近刚更新的,还在 MemStore
  • 可能最近刚读过,缓存在 Block Cache

所以,当你读一行 row 时,系统怎么将对应的 cells 返回呢?一次 read 操作会将 Block Cache,MemStore 和 HFile 中的 cell 进行合并:

  • 首先 scanner 从 Block Cache 读取 cells。最近读取的 KeyValue 都被缓存在这里,这是 一个 LRU 缓存。
  • 然后 scanner 读取 MemStore,即写缓存,包含了最近更新的数据。
  • 如果 scanner 没有在 BlockCache 和 MemStore 都没找到对应的 cells,则 HBase 会使用 Block Cache 中的索引和布隆过滤器来加载对应的 HFile 到内存,查找到请求的 row cells。每个 MemStore 可能会有多个 HFile,所以一次 read 请求可能需要多读个文件,这可能会影响性能,这被称为读放大read amplification)。

11、HBase Minor Compaction


HBase 会自动合并一些小的 HFile,重写成少量更大的 HFiles。这个过程被称为 minor compaction。它使用归并排序算法,将小文件合并成大文件,有效减少 HFile 的数量。

12、HBase Major Compaction


Major Compaction 合并重写每个 Column Family 下的所有的 HFiles,成为一个单独的大 HFile,在这个过程中,被删除的和过期的 cell 会被真正从物理上删除,这能提高读的性能。但是因为 major compaction 会重写所有的 HFile,会产生大量的硬盘 I/O 和网络开销。这被称为写放大Write Amplification)。Major compaction 可以被设定为自动调度。因为存在 write amplification 的问题,major compaction 一般都安排在周末和半夜。

13、HBase 故障恢复

当某个 Region Server 发生 crash 时,它所管理的 region 就无法被访问了,直到 crash 被检测到,然后故障恢复完成,这些 region 才能恢复访问。Zookeeper 依靠心跳检测发现节点故障,然后 HMaster 会收到 region server 故障的通知。

当 HMaster 发现某个 region server 故障,HMaster 会将这个 region server 所管理的 regions 分配给其它健康的 region servers。为了恢复出现故障的 region server 的 MemStore 中还未被持久化到 HFile 的数据,HMaster 会将 WAL 分割成几个文件,将它们保存在新的 region server 上。每个 region server 然后回放各自拿到的 WAL 碎片中的数据,来为它所分配到的新 region 建立 MemStore。

WAL 包含了一系列的修改操作,每个修改都表示一个 put 或者 delete 操作。这些修改按照时间顺序依次写入,持久化时它们被依次写入 WAL 文件的尾部。

当数据仍然在 MemStore 还未被持久化到 HFile 怎么办呢?WAL 文件会被回放。操作的方法是读取 WAL 文件,排序并添加所有的修改记录到 MemStore,最后 MemStore 会被刷写到 HFile。

故障恢复是 HBase 可靠性保障的一个重要特性。WAL 在这里扮演了关键角色,在分割 WAL 时,数据会根据 region 分配到对应的新的 region server 上,然后 region server 负责回放这一部分数据到 MemStore 中。

相关阅读:

  1. 深入理解 Hbase 架构(翻译)
  2. HBase Architecture: HBase Data Model & HBase Read/Write Mechanism